Interface gráfica com o usuário em BREW – Parte 2

Antonio Luiz Cavalcanti e João Alberto Amaral

Na edição anterior vimos como trabalhar com a API de interface gráfica de baixo nível. Nesse artigo completamos a interface gráfica da aplicação trabalhando com a API de alto nível, utilizando os componentes do framework padrão da plataforma BREW.

Interface com o usuário utilizando componentes do framework BREW

Como falado anteriormente, a plataforma BREW disponibiliza alguns componentes que facilitam o desenvolvimento de interfaces gráficas. Apesar desses componentes serem bastante customizáveis e fáceis de trabalhar, ainda é de responsabilidade do desenvolvedor fazer o ajuste de posicionamento em tela e o controle de foco do componente ativo.

Os componentes básicos da plataforma são:

·         IMenuCtl: componente que pode ser utilizado de quatro formas diferentes:

o        AEECLSID_MENUCTL: menu onde cada linha representa uma opção de menu que pode ser selecionada, permite adicionar um ícone a cada item do menu, e possui controle de scroll automático.

o        AEECLSID_LISTCTL: listagem de itens bastante simples, só permitindo adicionarmos texto a cada item. Também possui controle de scroll automático.

o        AEECLSID_SOFTKEYCTL: apresenta os itens como Soft Key. Seu posicionamento é automático de acordo com a localização padrão das SoftKeys do handset.

o        Barra de botões (ícones): implementa uma barra horizontal de botões (apenas ícones) onde é possível navegar e escolher a opção desejada.

·         ITextCtl: controle que permite a entrada de dados textuais pelo usuário. É bem flexível e aceita o modo de edição T9 quando o handset possui suporte a ele (ver Nota 1), porém o tipo de conteúdo deve ser controlado manualmente pelo desenvolvedor.

·         IDateCtl: controle para entrada de data. A data é selecionada utilizando-se as setas de navegação do handset.

·         ITimeCtl: semelhante ao controle de data, porém utilizado para hora.

 

Nas Tabelas 1, 2, 3 e 4 podemos ver as propriedades mais utilizadas desses componentes e algumas macros globais úteis nesse escopo.

 

Macros úteis

 

Macro

 

 

Parâmetros

 

SETAEERECT

 

Configura as dimensões do retângulo passado no primeiro parâmetro com os dados passados também por parâmetro. Essa estrutura AEERect é utilizada para definir o view port de um componente visual não permitindo que sua pintura extrapole essa área.

 

 

AEERect * rect

Retângulo a ser definido.

 

 

X

Posição no eixo x do retângulo.

 

 

Y

Posição no eixo y do retângulo.

 

 

width

Largura do retângulo.

 

 

height

Altura do retângulo.

 

GETTIMESECONDS

 

Essa macro devolve o valor da hora atual do celular em segundos seguindo o padrão da plataforma BREW de contagem (mais detalhes sobre esse padrão consulte o help do BREW SDK) . Utilizando ela em conjunto com a macro GETJULIANDATE obtemos uma estrutura com a data atual configurada.

 

 

Sem parâmetros

 

 

GETJULIANDATE

 

Configura os dados sobre a data passada como um inteiro em uma estrutura JulianDate.

 

 

uint32 dwSecs

Data/hora configurada em um inteiro normalmente obtida a partir da macro GETTIMESECONDS.

 

 

JulianType *pDate

Estrutura que terá seus campos configurados com os dados obtidos a partir de dwSecs.

 

ISHELL_CreateInstance

 

Macro genérica que instancia qualquer componente gráfico (e outros não gráficos) a partir do identificador de tipo do componente.

 

 

IShell * pIShell

Instância do Shell da aplicação.

 

 

AEECLSID cls

Identificador único do tipo do controle. No nosso caso usaremos: AEECLSID_ SOFTKEYCTL para menus, AEECLSID_DATECTL para date fields e AEECLSID_TEXTCTL para text fields.

 

 

void  **pObject

Ponteiro que retorna a instância do controle .

Tabela 1. Macros úteis da plataforma.

 

IMenuCtl

 

Função

 

 

Parâmetros

 

IMENUCTL_SetColors

 

Possibilita configurar o padrão de cores que o menu adotará.

 

 

IMenuCtl * pIMenuCtl

Instância do IMenu a ser configurado.

 

 

AEEMenuColors * pc

Estrutura com as cores desejadas.

 

IMENUCTL _SetActive

 

Seta o foco da aplicação no IMenu passado por parâmetro.

 

 

IMenuCtl * pIMenuCtl

Instância do IMenu a receber foco.

 

IMENUCTL _AddItem

 

Adiciona um item ao menu.

 

 

IMenuCtl * pIMenuCtl

Instância do IMenu a ser configurado.

 

 

const char * pszResFile

Nome do arquivo de recursos da aplicação. Pode ser NULL caso o texto a ser configurado por parâmetro seja passado em pText.

 

 

uint16 wResID

Nome do ID que identifica a string a ser carregada dos arquivos de recursos para configurar o texto desse Item (caso pszResFile for diferente de NULL).

 

 

uint16 nItemID

Identificador único do item do menu. É através desse identificador que sabemos qual dos itens do menu foi acionado.

 

 

AECHAR * pText

Texto a ser configurado no item do menu caso pszResFile seja passado como NULL.

 

 

uint32 lData

Parâmetro que pode ser utilizado pelo desenvolvedor para configurar dados relativos à aplicação.

 

IMENUCTL_Release

 

Libera memória de um componente IMenuCtl previamente criado pela função ISHELL_CreateInstance.

 

 

IMenuCtl * pMenu

Instância do IMenu que queremos liberar.

Tabela 2. Métodos da interface IMenuCtl.

 

ITextCtl

 

Função

 

 

Parâmetros

 

ITEXTCTL_SetProperties

 

Função que configura o comportamento e aparência do componente. Existem diversas configurações a serem utilizadas (consultar o help do BREW SDK para a lista completa de opções).

 

 

ITextCtl * pITextCtl

Instância do IText a ser configurada.

 

 

uint32 dwProps

Parâmetro com as configurações desejadas. Dentre as que utilizamos são:

TP_FRAME – Solicita a pintura do retângulo em volta do text field.

TP_FIXSETRECT – Limita a pintura do text field a área configurada por SetRect

 

ITEXTCTL_SetRect

 

Define as dimensões do componente com um AEERect previamente configurado pela macro SETAEERECT.

 

 

ITextCtl * pITextCtl

Instância do IText a ser configurada.

 

 

AEERect * rect

Retângulo já configurado.

 

ITEXTCTL_SetTitle

 

Define a label do componente.

 

 

ITextCtl * pITextCtl

Instância do IText a ser configurada.

 

 

const char * pszResFile

Nome do arquivo de recursos da aplicação. Pode ser NULL caso o texto a ser configurado por parâmetro seja passado em pText.

 

 

uint16 wResID

Nome do ID que identifica a string a ser carregada dos arquivos de recursos para configurar o texto desse item (caso pszResFile for diferente de NULL).

 

 

AECHAR * pText

Texto a ser configurado na label caso pszResFile seja passado como NULL.

 

ITEXTCTL_Release

 

Libera memória de um text field previamente criado pela função ISHELL_CreateInstance.

 

 

ITextCtl * pText

Instância do text field que queremos liberar.

Tabela 3. Métodos da interface ITextCtl.

 

IDateCtl

 

Função

 

 

Parâmetros

 

IDATECTL_SetFont

 

Função utilizada para definir a fonte a ser apresentada pelo controle.

 

 

IDateCtl * pIDateCtl

Instância do controle DateCtl a ser configurada.

 

 

AEEFont fntText

Fonte a ser apresentada no texto do controle.

 

 

AEEFont fntTitle

Fonte a ser apresentada na label do controle.

 

IDATECTL_SetRect

 

Define as dimensões do componente com um AEERect previamente configurado pela macro SETAEERECT.

 

 

IDateCtl * pIDateCtl

Instância do controle DateCtl a ser configurada.

 

 

AEERect * rect

Retângulo já configurado.

 

IDATECTL_SetTitle

 

Função que define o texto da label do componente.

 

 

IDateCtl * pIDateCtl

Instância do controle DateCtl a ser configurada.

 

 

const char * pszResFile

Nome do arquivo de recursos da aplicação. Pode ser NULL caso o texto a ser configurado por parâmetro seja passado em pText.

 

 

uint16 wResID

Nome do ID que identifica a string a ser carregada dos arquivos de recursos para configurar o texto desse Item (caso pszResFile for diferente de NULL).

 

 

AECHAR * pText

Texto a ser configurado na label caso pszResFile seja passado como NULL.

 

IDATECTL_SetDate

 

Seta o valor da data que deve ser exibida pelo componente.

 

 

IDateCtl * pIDateCtl

Instância do controle DateCtl a ser configurada.

 

 

unsigned int nYear

Ano que deve ser exibido.

 

 

unsigned int nMonth

Mês que deve ser exibido.

 

 

unsigned int nDay

Dia que deve ser exibido.

 

IDATECTL_Release

 

Libera memória de um date field previamente criado pela função ISHELL_ CreateInstance.

 

 

IDateCtl * pDate

Instância do date field que queremos liberar.

Tabela 4. Métodos da Interface IDateCtl.

 

Nota 1. O que é T9?

T9, ou Texto em 9 teclas ou ainda no original Text on 9 keys, é uma API de predição de texto para dispositivos com teclados restritos como os dos celulares. Ela é baseada em dicionários específicos de cada língua e prevê em uma seqüência de toques únicos por tecla qual o texto que está sendo digitado sem que o usuário de celular seja obrigado a digitar uma mesma tecla várias vezes para chegar a letra que deseja. As evoluções do T9 prevêem o aprendizado de novas palavras digitadas com freqüência pelo usuário como abreviações não previstas em dicionários ou até mesmo apelidos carinhosos dados à namorada. É uma funcionalidade muito importante quando falamos de usabilidade em dispositivos móveis e até pouco tempo era uma API restrita às funcionalidades do celular como SMS, mas aos poucos está sendo implementada e liberada nas mais diversas plataformas como BREW, JavaME e Symbiam.

Componentes do framework BREW utilizados em nosso estudo de caso

Em nosso estudo de caso utilizamos três componentes para criação da tela de entrada de dados de abastecimento: um IDateCtl para entrada da data do abastecimento, três ITextCtl para entrada da quantidade de litros, o valor do abastecimento e da quilometragem do carro e, por fim, um IMenuCtl para criação do menu de Softkeys da tela. Para realizar a adição e configuração dos componentes na interface gráfica com o usuário, criamos cinco macros C (ver Nota 2) que facilitam o nosso trabalho e diminuem o código duplicado nas telas destino. Vejamos o arquivo Screen.h (Listagem 3) para conhecer essas macros.

 

Nota 2. Macros em C e C++

As macros são uma importante funcionalidade em C. Com ela podemos definir desde uma constante até um fragmento de código que deve ser substituído toda vez que o pré-processador encontrar a referência da macro. Quando compilamos um código em C a primeira tarefa do compilador é acionar o pré-processador para substituir as ocorrências das macros pelo seu conteúdo. Por exemplo:

 

Uma vez definida a macro SOMA(a,b)

 

#define SOMA(a,b) a+b

 

Quando a utilizarmos em qualquer parte do código como:

 

int somaInteiros(int x, int y){

         return SOMA(x,y);

}

 

int somaDecimais(float x, float y){

         return SOMA(x,y);

}

 

Após a passagem do pre-processador o código que é mandado para a compilação será:

 

int somaInteiros(int x, int y){

         return x+y;

}

 

int somaDecimais(float x, float y){

         return x+y;

}

 

Perceba que só foi substituída a ocorrência da macro pelo seu conteúdo. Isso nos permite criar um código extenso, por exemplo, que será utilizado muitas vezes no programa e sua chamada ser uma simples palavra. Nesse momento nos perguntamos por que utilizar macros e não uma função que faz o trabalho? Bem, existem diversos motivos para isso, um dos mais importantes é que como a macro é copiada para dentro do código que a chama (chamamos isso de código in-line, que também pode ser feito através de funções in-line) temos uma melhoria no desempenho, pois não precisamos fazer o empilhamento de uma chamada a outra função. A grande desvantagem disso é que uma utilização demasiada desse tipo de estratégia pode "dilatar" o código da aplicação aumentando muito o tamanho do executável final. Percebemos então que as macros devem ser utilizadas com critério.

 

Screen Header File

 

001 #ifndef SCREEN_H

002 #define SCREEN_H

003

004 /*--------------------------------------------------------------------------

005   Includes

006   -------------------------------------------------------------------------- */

007 #include "FuelManager.h"

008

009 #include "AEEMenu.h"

010 #include "AEEDate.h"

011 #include "AEEText.h"

012

013 /*--------------------------------------------------------------------------

014   Constantes

015   -------------------------------------------------------------------------- */

016 //Espaço entre os componentes da tela, em pixels

017 #define COMPONENT_GAP 4

018 //Largura dos controles de adição, em pixels

019 #define COMPONENT_WIDTH ownerApplet->m_DeviceInfo.cxScreen - 10

020 //Altura dos controles de edição, em pixels

021 #define COMPONENT_HEIGHT 28

022

023 /*--------------------------------------------------------------------------

024   Macros

025   -------------------------------------------------------------------------- */

026 //Macro que simplifica a criação dos componentes gráficos da plataforma brew.

027 #define  CREATE_SCREEN_CONTROL(type,cotrolPointer)                          \

028    ISHELL_CreateInstance(ownerApplet->a.m_pIShell,type,(void**)&(cotrolPointer))

029

030 //Macro que simplifica a configuração de um componente TextCtl

031 #define ADD_TEXT_FIELD(textField, rect, resource_file, resource_label)      \

032    SETAEERECT( &rect, 5, rect.y+COMPONENT_HEIGHT+COMPONENT_GAP,             \

033                COMPONENT_WIDTH, COMPONENT_HEIGHT );                         \

034    ITEXTCTL_SetProperties( textField, TP_FRAME | TP_FIXSETRECT);            \

035    ITEXTCTL_SetRect( textField, &rect );                                    \

036    ITEXTCTL_SetTitle( textField, resource_file, resource_label, NULL );

037

038 //Macro que simplifica a configuração de um componente DateCtl

039 #define ADD_DATE_FIELD(date_field, rect, resource_file, resource_label)     \

040    SETAEERECT( &rect, 5, 5, COMPONENT_WIDTH, COMPONENT_HEIGHT );            \

041    IDATECTL_SetRect( date_field, &rect );                                   \

042    IDATECTL_SetFont( date_field, AEE_FONT_NORMAL, AEE_FONT_BOLD);           \

043    IDATECTL_SetTitle( date_field, resource_file, resource_label, NULL );    \

044    JulianType date;                                                         \

045    GETJULIANDATE(GETTIMESECONDS(), &date);                                  \

046    IDATECTL_SetDate( date_field, date.wYear, date.wMonth, date.wDay);       \

047    IDATECTL_EnableCommand( date_field, TRUE, DATE_SELECT);

048

049 //Macro que simplifica a criação de softkeys

050 #define ADD_SOFTKEY_MENU(menu)                                              \

051    AEEMenuColors sftKeyColors;                                              \

052    sftKeyColors.cBack = MAKE_RGB(0x0a, 0x0d, 0x52);                         \

053    sftKeyColors.cText = MAKE_RGB(0xFF,0xFF,0xFF);                           \

054    sftKeyColors.wMask = MC_BACK | MC_TEXT;                                  \

055    IMENUCTL_SetColors( menu, &sftKeyColors);                                \

056    IMENUCTL_SetActive( menu, FALSE);

057

058 #define ADD_SOFTKEY_ITEM(softKeyMenu, resource_file, item_id)               \

059    IMENUCTL_AddItem(   softKeyMenu, resource_file, item_id, item_id, NULL, item_id );          

060

061 /**

062  * Classe base para todas as telas da aplicação. Deve ser estendida tanto pelas

063  * telas que se utilizam das APIs de baixo nível como as que se utilizam das APIs

064  * das de alto nível.

065  */

066 class Screen{

067

068 protected:

069     /** Applet que criou a tela. */

070     FuelManager  *ownerApplet;

071    

072     /**

073     * Método virtual puro que deve ser implementado por toda interface que

074     * necessite de controle de foco.

075     * @param eCode Código do evento gerado.

076     * @param wParam Dado do evento

077     * @param dwParam Dado do evento

078     */

079     virtual boolean componentsFocusControl(AEEEvent eCode, uint16 wParam,uint32 dwParam)=0;

080 public:

081

082     /**

083     * Método virtual puro que deve ser sempre implementado pela tela concreta.

084     * É chamado tanto pelos eventos de re-pintura do Applet como pelo próprio

085     * desenvolvedor quando é necessário repintar a tela.

086     */

087     virtual void draw() = 0;

088

089     /**

090     * Método virtual puro que deve ser sempre implementado pela tela concreta.

091     * É um by pass do método AEEApplet_HandleEvent();

092     * @param eCode Código do evento gerado.

093     * @param wParam Dado do evento

094     * @param dwParam Dado do evento

095     */

096     virtual boolean handle_Event(AEEEvent eCode, uint16 wParam,uint32 dwParam)=0;

097

098     void sendEvent(AEEEvent event, uint16 wParam, uint32 dwParam){

099          ISHELL_PostEvent(this->ownerApplet->a.m_pIShell,

100                           this->ownerApplet->a.clsID,

101                           event,wParam,dwParam);

102     }

103

104     /**

105     * Método virtual que deve ser sobrescrito quando a tela precisar de um destrutor.

106     */

107     virtual ~Screen(void){};

108 };

109

110 #endif

111

Listagem 1. Código Fonte da classe abstrata Screen.

 

As macros utilizadas foram:

1.      CREATE_SCREEN_CONTROL: utilizada para criar um componente de interface gráfica com o usuário. Encapsula o uso da função ISHELL_CreateInstance (Listagem 1 linha 027).

2.      ADD_TEXT_FIELD: utilizada para configurar na tela um componente do tipo ITextCtl (Listagem 1 linha 031).

3.      ADD_DATE_FIELD: utilizada para configurar na tela um componente do tipo IDateCtl (Listagem 1 linha 039).

4.      ADD_SOFT_KEY_MENU: utilizada para configurar o menu de Softkeys na tela (Listagem 1 linha 050).

5.      ADD_SOFT_KEY_ITEM: adiciona um item (Softkey) ao menu previamente configurado (Listagem 1 linha 038).

 

Após a criação das macros (Listagem 1), o código de montagem das telas fica limpo e simples de entender (método Draw da classe AddViewRefuellingScreen Listagem 2).

A implementação da classe AddViewRefuellingScreen (Listagem 2) é bem semelhante à da classe MainMenuScreen (Vista na edição anterior da Web Mobile), porém dois métodos de AddViewRefuellingScreen merecem ser comentados, o draw() (linha 129, do arquivo cpp, Listagem 2) e o construtor (linha 004 do arquivo cpp Listagem 2). Em ambos os métodos utilizamos as macros explicadas na classe Screen (Listagem 1) para facilitar a criação dos componentes e com isso economizamos bastante escrita de código. Também é interessante notar que, por causa das macros, não precisamos definir as posições dos controles (coordenadas x,y da tela) e com isso o código ficou muito mais  limpo que o mesmo método da classe MainMenu.

 

AddViewRefuellingScreen Header File

 

001 #ifndef ADD_VIEW_REFUEL_H

002 #define ADD_VIEW_REFUEL_H

003

004 /*------------------------------------------------------------------

005   Includes

006   ------------------------------------------------------------------*/

007 #include "Screen.h"

008

009

010 /**

011  * Tela de cadastro do abastecimento, utilizada tanto na edição

012  * quanto visualização do registro.

013  */

014 class AddViewRefuelScreen : public Screen {

015 private:

016     /** Controle do campo de Data do abastecimento. */

017     IDateCtl   *pDate;

018

019     /** Controle do campo de litros do abastecimento. */

020     ITextCtl   *pTextLitros;

021

022     /** Controle do campo de valor do abastecimento. */

023     ITextCtl   *pTextValor;

024

025     /** Controle do campo de quilometragem do abastecimento. */

026     ITextCtl   *pTextOdometroTotal;  

027

028     /** Softkeys. */

029     IMenuCtl       *m_pMenu;

030

031 protected:

032     /**

033     * Implementação do método virtual da classe Screen.

034     * Ver documentação do método em Screen.h

035     */

036     boolean componentsFocusControl(AEEEvent eCode, uint16 wParam,uint32 dwParam);

037

038 public:

039     /** Implementação do método virtual da classe Screen. */

040     AddViewRefuelScreen(FuelManager *fuelManager);

041

042     /**

043     * Implementação do método virtual da classe Screen.

044     * Ver documentação do método em Screen.h

045     */

046     void draw(void);

047

048     /**

049     * Implementação do método virtual da classe Screen.

050     * Ver documentação do método em Screen.h

051     */

052     boolean  handle_Event(AEEEvent eCode, uint16 wParam,uint32 dwParam);

053

054    

055     /** Detrutor da classe. */

056     ~AddViewRefuelScreen(void);

057

058 };

059

060 #endif

061

AddViewRefuellingScreen CPP

 

001

002 #include "AddViewRefuelScreen.h"

003 /* Ver arquivo de header para ler a documentação do método. ---------------- */

004 AddViewRefuelScreen::AddViewRefuelScreen(FuelManager *fuelManager) {

005     this->ownerApplet = fuelManager;

006     //Criação dos componentes de tela

007     CREATE_SCREEN_CONTROL( AEECLSID_DATECTL, this->pDate);

008     CREATE_SCREEN_CONTROL( AEECLSID_TEXTCTL, this->pTextLitros );

009     CREATE_SCREEN_CONTROL( AEECLSID_TEXTCTL, this->pTextValor );

010     CREATE_SCREEN_CONTROL( AEECLSID_TEXTCTL, this->pTextOdometroTotal );

011     CREATE_SCREEN_CONTROL( AEECLSID_SOFTKEYCTL, this->m_pMenu );

012     //Adicionando o menu de softkeys

013     ADD_SOFTKEY_MENU( this->m_pMenu);

014     //Adicionando os item de menu

015     ADD_SOFTKEY_ITEM(this->m_pMenu, FUELMANAGER_RES_FILE, BUTTON_BACK);

016     ADD_SOFTKEY_ITEM(this->m_pMenu, FUELMANAGER_RES_FILE, BUTTON_SAVE);

017     //Configurando as cores da tela

018     IDISPLAY_SetColor( ownerApplet->a.m_pIDisplay,

019           CLR_USER_TEXT, MAKE_RGB(0x00,0x00,0x00) );

020     IDISPLAY_SetColor( ownerApplet->a.m_pIDisplay,

021           CLR_USER_BACKGROUND, MAKE_RGB(0xA8, 0xC4, 0xF5) );

022     IDISPLAY_SetColor( ownerApplet->a.m_pIDisplay,

023           CLR_USER_FRAME, MAKE_RGB(0x00,0xFF,0x00));

024

025     this->draw();

026 }

027

028

029     … Código omitido por questão de clareza.

        

128 /* Ver arquivo de header para ler a documentação do método. ---------------- */

129 void AddViewRefuelScreen::draw(void)

130 { 

131     //Buffer usado para carregar as strings do arquivo de recursos

132     AECHAR resBuffer[100];

133

134     //Retângulo utilizado para definer as dimensões dos compoenentes gráficos

135     AEERect rect = {0};

136

137     //Configuração do campo de Data

138     ADD_DATE_FIELD(this->pDate, rect, FUELMANAGER_RES_FILE, ADD_SCREEN_LABEL_DATE)

139

140     //Configuração do campo de Litres

141     ADD_TEXT_FIELD(this->pTextLitros, rect, FUELMANAGER_RES_FILE, ADD_SCREEN_LABEL_LITRES)

142

143     //Configuração do campo de Value

144     ADD_TEXT_FIELD(this->pTextValor, rect, FUELMANAGER_RES_FILE, ADD_SCREEN_LABEL_VALUE)

145

146     //Configuração do campo de Quilometragem

147     ADD_TEXT_FIELD(this->pTextOdometroTotal, rect,

148                       FUELMANAGER_RES_FILE,ADD_SCREEN_LABEL_TOTAL_ODOMETER)

149

150

151     //Coloca o foco no componente de data

152     IDATECTL_SetActive( this->pDate, TRUE );

153

154     //Limpa a tela e aplica as cores previamente configuradas

155     IDISPLAY_ClearScreen( ownerApplet->a.m_pIDisplay );

156

157     //Atualiza os compoenentes no display

158     IDATECTL_Redraw( this->pDate );

159     ITEXTCTL_Redraw( this->pTextLitros);

160     ITEXTCTL_Redraw( this->pTextValor);

161     ITEXTCTL_Redraw( this->pTextOdometroTotal);

162     IMENUCTL_Redraw( this->m_pMenu);

163     IDISPLAY_Update( ownerApplet->a.m_pIDisplay);

164 }

165

166     … Código omitido por questão de clareza.

 

Listagem 2. Código fonte da classe AddViewRefuelScreen.

 

O resultado obtido com o método Draw da classe AddUpdateRefuellingScree pode ser visto na Figura 1.

 

brew01.JPG

Figura 1. Tela de cadastro de abastecimento.

O futuro do desenvolvimento de interfaces gráficas em BREW

A Qualcomm há muito tempo percebeu como é trabalhoso criar boas interfaces gráficas em BREW e lançou um framework muito mais completo, fácil de utilizar e customizável, chamado uiOne. É nesse ponto que fazemos a pergunta: por que aprender a utilizar a velha forma de trabalho com GUI em BREW se temos um jeito melhor de fazer agora? Pelo simples fato de que ainda demorará para que a indústria de handsets absorva a nova tecnologia e produza maciçamente dispositivos que a suportem. Enquanto isso, temos que continuar utilizando a “velha forma de fazer”.

O foco desse novo desenvolvimento é utilizar uma linguagem de marcação chamada TrigML, derivada de XML para descrição das interfaces que compõem a aplicação. Com isso, o desenvolvedor só precisa definir a tela através dessa linguagem de marcação e carregar esse documento na aplicação para que um engine da própria plataforma renderize o documento carregado.

Mais informações podem ser encontradas no site da Qualcomm em http://brew.qualcomm.com/bnry_brew/pdf/white_papers/uione_personalization_mobiledata.pdf. Exemplo de interfaces que podem ser desenvolvidas com o framework uiOne podem ser vistas na Figura 2.

 

brew02.JPG 

 

brew03.JPG

Figura 2. Exemplos de interfaces desenvolvidas com o framework uiOne.

Conclusões

Trabalhar com interface gráfica em BREW na maior parte do tempo é fácil, porém trabalhoso. Mesmo quando usamos os componentes disponibilizados pela plataforma ainda somos responsáveis pela maioria do controle das telas. A comunidade BREW tem aguardado com muito anseio a popularização do novo Framework de interface gráfica com o usuário, chamado uiOne. Com ele, o desenvolvimento de telas será feito escrevendo um simples documento XML e carregando-o pela aplicação. Enquanto o uiOne não é popularizado, continuamos a utilizar o framework básico da plataforma.

Boa sorte aos desenvolvedores e bons trabalhos.

 

Referências

Desenvolvendo em Brew – Uma introdução: Revista Web Mobile edição 10, Antonio Luiz Cavalcanti. O primeiro artigo da série.

 

Software Development for the QUALCOMM BREW Platform: Ray Rischpater, ISBN: 159059116x

 Um bom livro para estudo introdutório sobre a plataforma BREW. 

 

Wireless Game Development in C/C++ with BREW: Ralph Barbagalho, ISBN: 1556229054

Muito bom livro sobre desenvolvimento de Games em BREW. A segunda fonte é melhor como introdução, porém esse aborda algumas técnicas mais avançadas principalmente de utilização de interface gráfica de baixo nível.

 

http://brew.qualcomm.com/bnry_brew/pdf/white_papers/uione_personalization_mobiledata.pdf

Artigo da Qualcomm apresentando o uiOne.

 

http://www.developer.com/ws/brew/

Excelentes artigos sobre Brew. Desde nível mais iniciante até técnicas refinadas de controle do Watch Dog.

 

http://brew.qualcomm.com/brew/pt/developer/resources/dev_resources.html

Site oficial da Qualcomm com diversos tutoriais.

 

http://www.palowireless.com/brew/tutorials.asp

Endereço com bons tutoriais sobre a tecnologia, incluindo grandes fabricantes como Nokia e Motorola.

 

http://brewforums.qualcomm.com/

O fórum oficial Qualcomm sobre BREW. Primeiro lugar onde procuro respostas para minhas dúvidas. Só é preciso ser seletivo, pois alguns dos participantes postam dicas erradas.

image012.jpg

Antonio Luiz de O. Cavalcanti Jr. (alocj@cin.ufpe.br) Trabalha com desenvolvimento de software para dispositivos móveis e software embarcado há 4 anos. É atualmente Arquiteto de Software para aplicações móveis do CIN/UFPE (Centro de Informática da Universidade Federal de Pernambuco) em projetos de P&D para a Samsung. Detém as certificações oficiais Sun SCJA & SCJP. É pesquisador na área de complexidade algorítmica e processamento de sinais tendo algumas publicações sobre os temas.

image014.jpg

 

João Alberto da Silva Amaral (jasa@cin.ufpe.br) Engenheiro de Software para aplicações móveis do CIN/UFPE (Centro de Informática da Universidade Federal de Pernambuco) em projetos de P&D para a Samsung.  Bacharel em Ciência da Computação pela Universidade Federal de Pernambuco.