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.
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.
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.
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.
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.