84
ANDRÉ OLIVEIRA DA COSTA TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE INTERFACES GRÁFICAS EM LUA DI SSERTAÇÃO DE M ESTRADO 0 EPARTAi\t1ENTO DE INFORMÁTICA Po. 'T lFÍCL'\ U. 'l 'ERSID.'\DI e. TÓI lC ºº R IO or J 1 rLRO RI O Dl: ] ANbIRO, 30 Db ABRJL DE 1997

TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Embed Size (px)

Citation preview

Page 1: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

ANDRÉ OLIVEIRA DA COSTA

TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE INTERFACES GRÁFICAS EM LUA

DISSERTAÇÃO DE M ESTRADO

0 EPARTAi\t1ENTO DE INFORMÁTICA

Po. 'TlFÍCL'\ U. 'l 'ERSID.'\DI e. TÓI lC ºº R IO or J 1rLRO

RIO Dl: ] ANbIRO, 30 Db ABRJL DE 1997

Page 2: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

N.Cham. 004 C837t TESE UC

Titulo TKVIX - um toolkitpam construção de interfaces gráficas

11110111 Ex. I PUCB 0129671

--

Page 3: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

André Oliveira da Costa

TKVIX- UM TOOLJ<JT PARA CONSTRUÇÃO /. t< " ' , '• '

DE INTERFACES GKAFIOft.S EM LUA "li'' \ ,- ~ ' V

Dissertação apresentada ao Departamento de Informática da PUC-Rio como parte dos requi­sitos para a obtenção do título de Mestre em Informática: Ciências da Computação.

Orientador: Roberto Ierusalimschy

Departamento de Informática

Pontifícia Universidade Católica do Rio de Janeiro

Rio de Janeiro, 30 de abril de 1997

Page 4: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0
Page 5: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Ao meu avô Carlos

Page 6: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Agradecimentos

Aos J5, que vêm, como um todo, contribuindo (com enorme peso) para colocar estes anos na PUC-Rio dentre os melhores da minha vida. Individualmente, gostaria de agradecer ao Clinio por sua constante ajuda no que diz respeito à integração do toolkit TkVIX com o framework VIX, além dos inúmeros conselhos a respeito da arquitetura de TkVIX; ao Cassino por sua ajuda no que dizia respeito ao Canvas Draw; ao Renato Borges por sua inestimável ajuda com relação ao Motif e ao Xlib; ao Renato Cerqueira por ter sido um dos idealizadores de TkVIX, participando constantemente com conselhos; a todos pelos grandes amigos que são.

Ao Roberto, por ser responsável por muito do que sou hoje como Engenheiro de Computação, e pela amizade, orientação, paciência e falta de paciência.

Ao Cacá, que, como gerente, soube compreender minhas eventuais negligências ao TeCGraf devido à tese.

A todos no TeCGraf, por fazerem deste certamente o melhor ambiente de trabalho que jamais encontrarei - tanto no que diz respeito aos relacionamentos pessoais quanto à troca de conhecimentos técnicos.

Ao Prof. Gattass, por manter o TeCGraf como um centro de excelência, do qual sinto orgulho de ter participado, e por seu estilo único de gerência, sendo sempre uma pessoa acessível.

À toda minha família, principalmente ao meu pai, minha mãe, aos meus irmão e irmã e à minha avó, pelo excepcional ambiente familiar, companheirismo e pelo que sou hoje como pessoa. Um agradecimento especial ao meu avô, que foi responsável, sem que eu ou ele nos déssemos conta, por inúmeras e importantes lições de vida, e a quem considero um modelo a ser seguido, mesmo não estando mais entre nós.

Ao CNPq e ao SEPROC/CENPES/PETROBRÁS pelo auxílio financeiro.

Page 7: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Resumo

Este trabalho apresenta mais uma ferramenta que tem como objetivo oferecer suporte à criação de interfaces gráficas. A especificação de uma interface é feita obedecendo a sintaxe de Lua, uma linguagem interpretada de fácil aprendizado e utilização. O uso de Lua permite o desenvolvimento da interface em separado da aplicação, facilitando rápida prototipação.

Esta ferramenta, o toolkit TkVIX, foi desenvolvido em C++ e Lua, sobre um framework que abstrai os detalhes do sistema gráfico e implementa os conceitos de objetos e espaços visuais; os elementos de interface ( widgets) são implementados sobre estes conceitos. TkVIX oferece suporte a layout abstrato, além de permitir que widgets implementados por outros toolkits ( widgets nativos) sejam utilizados nas interfaces da mesma maneira que o são os widgets implementados diretamente por ele. A arquitetura modular de TkVIX foi concebida de modo a permitir que novos widgets, nativos ou não, possam ser a ele incorporados sem que seja necessário manutenção no próprio toolkit. As camadas que compõem o toolkit foram implementadas visando permitir alto grau de portabilidade.

Page 8: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Abstract

This work presents yet another tool designed to support the creation of graphical user interfaces. These interfaces are described according to the syntax of Lua, an interpreted language that can be easily learned and used. The use of Lua allows the development of the interface apart of that of the application, therefore making it suitable for rapid prototyping.

This tool, the TkVIX toolkit, was developed in C++ and Lua over a framework which hides the details of the graphical system underneath and implements the concepts of visual object and visual space; these concepts were used to implement the interface objects (widgets). TkVIX offers support to abstract layout, and allows the utilization of other toolkits' widgets (the so-called native widgets) in the sarne manner its own widgets are used. The modular architecture of TkVIX was conceived so that the incorporation of new widgets, be they native or not, does not imply in re-implementation of the toolkit itself. The layers that make up the toolkit were implemented aiming a high degree of portability.

Page 9: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Sumário

1 Introdução 1 1.1 Motivação e objetivo 3 1.2 Apresentação do trabalho 4

2 Ferramentas Existentes 5 2.1 O TeCGraf ..... 17 2.2 O Framework VIX 20

3 O Toolkit 24 3.1 A linguagem Lua 24 3.2 Hierarquia de classes 26

3.2.1 Widgets ... 26 3.2.2 Binding com o framework 34

3.3 O algoritmo para layout abstrato 38 3.3.1 Prioridades 39 3.3.2 Exemplos ......... 41

3.4 Integração com C++ . . . . . . . 51 3.4.1 O mecanismo de mensagens 51 3.4.2 Herança múltipla e conversão de tipos 53

3.5 Widgets nativos .... 55 3.5.1 Widgets Motif . ............. 56

4 Conclusão 64

Page 10: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Lista de Figuras

2.1 Serviços disponíveis ao programador no ambiente X Windows . 2.2 Diálogo para seleção de arquivos utilizando Athena Widget Set . 2.3 Diálogo com dois paned widgets dispostos verticalmente . 2.4 Diálogo para seleção de arquivos utilizando Motif 2.5 Filtros em VIX . . . . . . . . . . . . . . . . 2.6 Efeito "multiplexador" dos grupos em VIX 2. 7 Dispositivos em VIX . . . . . . .

6 7 8 9

21 22 23

3.1 Hierarquia de classes em Lua . . . 27 3.2 Botões implementados no toolkit 28 3.3 Exemplos de composições possíveis com menus . 29 3.4 Diálogos resultantes das especificações da Figura 3.3 . 29 3.5 Botões com labels de mais de uma linha . . 29 3.6 Impacto do atributo alignment em hboxes . . . . . . 30 3. 7 Impacto do atributo alignment em vboxes . . . . . . .. 30 3.8 Exemplo de simplificação conseguida com o atributo alignment 31 3.9 Diálogo simples contendo apenas um botão . . . . . . 32 3.10 Exemplo ilustrando a expansibilidade dos widgets . . . . . . . 33 3.11 Processamento do evento de RedrawAll pelo canvas . . . . . . 37 3.12 Diálogo com tamanho insuficiente para comportar os widgets . 39 3.13 Impacto da utilização de prioridades . . . 39 3.14 Distribuição de espaço entre fills e canvas. 42 3.15 Fills com mesma prioridade que o canvas . 42 3.16 Diálogo para confirmação . . . . . . 43 3.17 Toolbar . . . . . . . . . . . . . . . 44 3.18 Diálogo secundário do exemplo 3.3 45 3.19 Calculadora . . . . . . . . . . . . . 47 3.20 Diálogo construído com widgets nativos e não-nativos . 48 3.21 Diálogo do exemplo 3.6 . . . . . . . . . . . . . 49 3.22 Tipos de mensagens em C++ . . . . . . . . . . . . . . 52 3.23 Hierarquia de classes do filtro básico de VIX . . . . . . 53 3.24 Conversão de tipos entre ramos diferentes da hierarquia . 54 3.25 Hierarquia de classes de widgets nativos . . . . . . . . . 56 3.26 Conversão de coordenadas entre widgets Motif . . . . . . 59 3.27 Modelo proposto para o tratamento de eventos destinados a widgets Motif 60 3.28 Interceptação de eventos destinados a widgets Motif. . . . . . . . . . . . . 61

ii

Page 11: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

3.29 Combinação de widgets nativos e não-nativos 3.30 Janela-de-texto ................ .

lll

62 63

Page 12: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Lista de Tabelas

3.1 Mapeamento de classes C++ para Lua . 3..2 Campos da mensagem LuaGetFieldMsg .

iv

34 53

Page 13: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Lista de Exemplos

3.1 Prioridades . . . . . . . . . 3.2 3.3 3.4

Diálogo para confirmação . . . . . . . . . . Floating toolbar . . . . . . . Calculadora . . . . . . . . . . . . . .

3.5 Entrada de dados 3.6 Listas ................ .

V

41 41 43 46 47 48

Page 14: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Capítulo 1

Introdução

Os avanços na tecnologia - tanto a nível de hardware, com processadores poderosos, capazes de lidar com grandes volumes de operações gráficas de maneira eficiente, quanto a nível de software, com, por exemplo, a difusão e o amadurecimento do paradigma de orientação a objetos - têm popularizado o uso de interfaces gráficas para interação com o usuário (GUis), com níveis de sofisticação crescentes. Estas interfaces aparecem sob as mais diversas formas, possuindo, porém, denominadores comuns, tanto a nível dos objetos de interface utilizados, como botões, listas, menus, textos, quanto a nível das operações com o mouse, como drag e drag-and-drop.

Diversos toolkits para construção de GUis têm surgido, com o objetivo de facilitar este processo que, se realizado por meio de interação direta com o sistema gráfico nativo, tende a ser extremamente penoso: neste nível de abstração, a interface ~ tratada exclusivam~nte como um conjunto de janelas e eventos sobre estas. Basicamente, o papel dos toolkits é propiciar uma camada de abstração sobre o sistema gráfico nativo, oferecendo acesso a objetos de interface como os mencionados anteriormente. Estes objetos, conhecidos gene­ricamente pelo termo widget, · possuem associados a si uma representação gráfica e uma semântica; os eventos gerados pelo usuário são tratados de acordo com estes parâmetros, e a aplicação é notificada quando se mostrar necessário. Por exemplo, quando o botão do mouse é pressionado sobre um widget que representa um botão, sua aparência é alterada para indicar que se encontra pressionado; quando o botão do mouse é solto, o widget reassume sua aparência normal, e só então a aplicação é notificada de que o objeto de inter/ ace botão (e não o botão do mouse) foi pressionado, podendo então executar tarefas que eventualmente estejam associadas a tal ação. Vemos, portanto, que com o auxílio dos toolkits o programador é liberado tanto da tarefa de desenhar efetivamente os objetos de interface quanto da de gerenciar a interação do usuário com eles. Cabe a ele as tarefas de especificar a aparência da interface, as relações entre os objetos nela presentes e seu comportamento frente aos eventos gerados pelo usuário.

Alguns toolkits possibilitam que o programador crie seus próprios objetos de interface, acrescentando-os ao seu conjunto original. Esta tarefa, porém, pode envolver um esforço considerável, dependendo do tipo de objeto que esteja envolvido e da maneira como o toolkit implementa os widgets sobre o sistema gráfico.

Quase tão importante quanto os widgets em si é a questão que diz respeito às ma­neiras de se agrupar os mesmos. Por agrupar entende-se criar relações de "paternidade"

1

Page 15: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

entre widgets: existem tipos especiais de widgets, conhecidos como grupos ou, mais for­malmente, widgets de composição, que possuem como característica o fato de possuírem um ou mais widgets "filhos". Nada impede que filhos possam ser eles próprios grupos, o que permite hierarquização da descrição da interface, resultando no que chamaremos nesta dissertação de árvore de elementos. Outra funcionalidade comumente associada a widgets de composição é a de determinar a disposição espacial dos seus filhos. Com o ob­jetivo de oferecer mais recursos para a construção de GUls, é comum os toolkits possuírem diferentes widgets de composição, cada qual associado a uma diferente política de layout; como exemplos de toolkits que seguem esta tendência, podemos citar Motif [9), Athe­na Widget Set [19] e Fresco (13]. À capacidade de widgets posicionarem outros widgets automaticamente (sem que a aplicação tenha que interceder), de acordo com heurísticas determinadas, convencionou-se denominar layout abstrato. Este modelo contrasta com o de la.yout concreto, onde a posição de cada widget deve ser determinada, pela aplicação, em termos das suas coordenadas 2D, o que evidentemente representa um aumento con­siderável no esforço para se criar e gerenciar a interface. Por exemplo, consideremos a situação em que as dimensões de um diálogo são alteradas: se foi utilizado layout abstra­to, os objetos são reposicionados automaticamente; se utilizou-se layout concreto, porém, cabe à aplicação recalcular as posições de cada widget. Um exemplo de toolkit que não provê recursos para Jayout abstrato é Visual Basic [15].

Embora a funcionalidade tipicamente associada a grupos seja a de hierarquizar a descrição da interface e dispor seus filhos de acordo com políticas de layout, existem toolkits que implementam grupos com a capacidade de tratar os eventos antes de repassá­los aos seus filhos. Um exemplo de toolkit com esta característica é Fresco [13], onde este papel cabe a widgets denominados viewers. Estes widgets podem, inclusive, determinar que todos os eventos de um tipo específico sejam a ele enviados, independente de fatores como a posição corrente do mouse, por exemplo; este comportamento caracteriza o que é conhecido por event grab. Uma vez interceptado pelo viewer, o evento pode ser por ele alterado antes de ser propagado aos filhos.

Outros toolkits oferecem mecanismos próprios para interceptação de eventos, em níveis diferentes do que o propiciado por Fresco. Em SUIT [5), por exemplo, o programador pode registrar rotinas, denominadas event traps, que serão executadas antes que cada evento seja despachado pelo Joop de eventos do toolkit. Estas rotinas recebem o evento ocorrido e o objeto sob o cursor quando do acontecimento do evento, e são responsáveis por retornar ao toolkit o objeto sobre o qual o evento será aplicado; isto permite, por exemplo, redirecionamento de eventos, caso uma event trap retorne um objeto diferente daquele a ela enviado como alvo do evento, ou a supressão dos mesmos, caso a rotina não retorne objeto algum.

Embora também se trate de um pré-processamento de eventos, há uma diferença , conceitua} importante entre o mecanismo implementado por SUIT e aquele implementado por Fresco: em SUIT, o pré-processamento acontece a um nível global, isto é, todo evento coletado pelo loop de eventos do toolkit é repassado aos event tra.ps. Já em Fresco, nós da árvore de elementos decidem como os eventos são repassados aos seus filhos.

A capacidade de grupos terem alguma influência nos eventos que serão repassados aos objetos agrupados oferece um leque de novas possibilidades na manipulação de objetos de interface em toolkits com suporte a objetos ativos, além de ter importante papel

2

Page 16: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

na coerência apresentada pela interface. Um exemplo ilustrativo é a combinação dos modelos abstrato e concreto de posicionamento de elementos; o layout abstrato poderia ser oferecido por grupos que não permitem manipulação direta dos elementos agrupados; os grupos utilizados para posicionamento concreto de elementos permitiriam esse tipo de operação. Os objetos agrupados não precisam estar cientes do tipo de grupo em que se encontram: os eventos envolvidos em operações de manipulação direta é que serão (ou não) repassados pelos grupos.

Outro recurso oferecido por alguns toolkits, que tem contribuído para sua melhor aceitação entre os desenvolvedores de aplicações com interface gráfica, é a possibilidade de se utilizar linguagens interpretadas para descrição da interface (e, em alguns casos, para interagir com a aplicação em tempo de execução), permitindo prototipação mais rápida das aplicações. Como exemplos, podemos citar aqui UIL, utilizada por Motif, LED, utilizada por IUP (12], e Tcl, utilizada por Tk (17].

1.1 Motivação e objetivo

A capacidade de redução de esforço proporcionada por toolkits específicos para construção de GUis, no que diz respeito ao desenvolvimento de aplicações com interface gráfica com o usuário, motivou o desenvolvimento do toolkit TkVIX, tema central desta dissertação.

Através da análise de diferentes toolkits existentes, identificou-se características que têm impacto direto na "usabilidade" de toolkits para construção de GUis, seja do ponto de vista do usuário final (aquele que, essencialmente, apenas interagirá com os elementos de interface), seja do ponto de vista do desenvolvedor de aplicações. Procurou-se incorporar a TkVIX o maior número de características positivas possível e evitar-se as consideradas negativas, tendo-se sempre a preocupação de se ter uma ferramenta de design simples. Assim, TkVIX oferece recursos tais como layout abstrato, descrição e manipulação. da interface através de uma linguagem interpretada poderosa de fácil sintaxe e utilização e desenvolvimento da interface independentemente da aplicação. Com relação ao suporte a layout abstrato, implementou-se em TkVIX um algoritmo especialmente desenvolvido para este toolkit, baseado no algoritmo implementado por IUP mas com características próprias, como suporte a elementos expansíveis. Dedicou-se também especial atenção à capacidade de incorporação de widgets implementados por outros toolkits (conhecidos como widgets nativos), de modo que elementos de interface complexos, como listas de elementos, assim como aqueles simples na sua aparência mas de complexa implementação, como caixas de texto, não precisem ser re-implementados, podendo ser utilizados em conjunto com os widgets implementados diretamente por TkVIX, da mesma maneira que estes são utilizados. A arquitetura de TkVIX foi concebida e implementada de tal maneira que sua expansão não implique em manutenção no código do próprio toolkit. Outra característica de TkVIX é a utilização dos conceitos de objeto e espaço visual, o que permite, entre outras coisas, que nós intermediários da árvore de elementos de interface possam tratar eventos antes de propagá-los.

A portabilidade de TkVIX também mereceu atenção: a interação com o sistema gráfico nativo é feita através de uma camada desenvolvida especialmente para este fim; esta camada, denominada Canvas Draw, foi implementada utilizando-se a linguagem C, e possui versão para diferentes plataformas. Sobre esta camada, situa-se um framework,

3

Page 17: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

denominado VIX [7), responsável pela implementação dos conceitos de objeto e espaco visual, implementado em C++. Sobre o framework, por sua vez, implementou-se um conjunto de classes que têm corno objetivo prover a base para a implementação do conceito de widget e a integração com a linguagem Lua [20], utilizada na descrição/manipulação da interface e responsável efetivamente pela implementação do conceito de widget. Lua foi implementada em ANSI C; seu código é compilado para diversas plataformas sem que seja necessário nenhuma alteração.

Este documento tem corno objetivo descrever o toolkit TkVIX no que diz respeito à sua arquitetura, sua ligação com o framework VIX, os conceitos envolvidos na sua concepção, suas características e suas limitações.

1.2 Apresentação do trabalho

Os demais capítulos desta dissertação foram organizados da seguinte forma: o Capítulo 2 apresenta urna análise de algumas ferramentas existentes com propósitos semelhantes a TkVIX; a Seção 2.2 apresenta o framework VIX, sobre o qual foi construído TkVIX. O Capítulo 3 apresenta brevemente a linguagem Lua, focalizando as características mais re­levantes para sua utilização de urna maneira geral e, em particular, com o toolkit TkVIX. Veremos também, neste capítulo, o conjunto de widgets implementado, o algoritmo para layout abstrato, o binding com o framework VIX, a integração entre Lua e C++ através de um mecanismo de mensagens e a utilização de widgets nativos. No Capítulo 4, apre­sentamos algumas conclusões obtidas deste trabalho; discutimos também a evolução de TkVIX, propomos melhoramentos e apresentamos tecnologias que poderiam ser incorpo­radas ao toolkit, ampliando sua funcionalidade.

4

Page 18: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Capítulo 2

Ferramentas Existentes

Em todo o mundo, várias instituições acadêmicas e comerciais têm se dedicado ao desen­volvimento de toolkits para construção de GUis. Analisaremos neste capítulo algumas das ferramentas existentes com esta finalidade.

Existe uma variedade de toolkits disponíveis; dedicamos maior atenção àqueles que são utilizados extensivamente, seja pela qualidade estética e funcional do produto final, seja pela disponibilidade e facilidade de uso, ou àqueles que trazem inovações para as tec­nologias envolvidas na construção de GUis; dentre as inovações apresentadas destacamos a utilização de linguagens interpretadas, o suporte à distribuição, arquiteturas cliente­servidor e object embedding. Alguns toolkits analisados não constam deste trabalho, por consistir basicamente de superconjuntos de outros, como é o caso de Tix [11], que é uma extensão de Tk [17], ou por possuírem uma finalidade muito específica, como é o c~o de Pacco [4], que, embora suporte distribuição de objetos, destin·a-se principalmente ao processamento distribuído de imagens.

Apresentamos a seguir um pequeno resumo das características das ferramentas pes­quisadas. Cabe aqui uma observação válida para esta dissertação como um todo: por se tratarem os toolkits de ferramentas que têm como função auxiliar o desenvolvimento de aplicações com interface gráfica, o usuário típico de um toolkit é o programador res­ponsável por tal tarefa, e não o usuário final - aquele que essencialmente interage com a aplicação. Ao longo deste documento, utilizaremos explicitamente a classificação usuário final para nos referirmos a esta segunda classe de usuários, e apenas usuário para nos referirmos ao desenvolvedor de aplicações.

Athena Widget Set

O Athena Widget Set [19] foi o primeiro toolkit disponível para o sistema X Windows [24] utilizado em maior escala. Implementado sobre o Intrinsics [1], seu papel é abstrair detalhes das camadas inferiores (ver Figura 2.1), tornando a utilização de widgets na construção de GUls menos penosa para o programador.

Xlib é a camada mais básica, no ambiente X Windows, em termos de sistema gráfico, consistindo das bibliotecas de funções para a.cesso aos recursos dos dispositivos a nível de primitivas gráficas, como, por exemplo, desenho de linhas e textos e cópia de imagens. Cabe também ao Xlib o tratamento dos eventos gerados pelo usuário e daqueles gerados pelo sistema gráfico nativo. como o desobscurecimento e o redimensionamento de jane-

5

Page 19: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Aplicação

l Widget Sets (lfmlkit.v)

t lntrinsics

l X Window Sysiem

Sisiema Operacional

Hlllldware

Figura 2.1: Serviços disponíveis ao programador no ambiente X Windows

las, em um nível bastante básico. O Intrinsics tem como funcionalidade básica oferecer recursos para a criação de widgets; os toolkits para construção de GUis utilizam estes recursos na criação dos widgets que disponibilizam ao programador, livrando-o portanto dos inúmeros detalhes envolvidos neste processo.

Analisando mais atentamente a Figura 2.1, podemos perceber que a aplicação possui interface com todas as camadas. Isto quer dizer que uma aplicação que utilize o toolkit Athena na construção de sua interface gráfica com o usuário pode se ver obrigada, depen­dendo da sua complexidade, a executar funções não apenas desta camada, mas também do Intrinsics e do Xlib. Estes fatores - saber o que executar, quando executar e como os diferentes níveis interagem entre si - contribuem para que a utilização do Athena Wid­get Set seja não-trivial. Veremos mais adiante que este problema não é exclusivo deste toolkit, e que a atenuação do esforço associado ao aprendizado da ferramenta é meta de vários outros toolkits existentes.

Se o compararmos aos padrões estéticos e funcionais das interfaces gráficas existentes hoje em dia (MS Windows, Motif etc.), o toolkit Athena é rudimentar no que diz respeito tanto à aparência quanto à variedade e funcionalidade dos widgets disponíveis. Como exemplo, a Figura 2.2 mostra um diálogo para seleção de arquivos construído com este toolkit.

Porém, apesar de suas deficiências estéticas e funcionais, o toolkit Athena é ainda utilizado por programadores no desenvolvimento de aplicações para o sistema X Windows. Alguns fatores que contribuem para isto são:

• o Athena Widget Set faz parte da distribuição padrão do X Windows, estando portanto disponível para toda plataforma que utilize este sistema gráfico;

• aplicações construídas com este toolkit tendem a exigir menos recursos da máquina do que as construídas com outros tooJkits, devido à simplicidade dos widgets.

Cabe ressaltar aqui o papel desempenhado pelo Intrinsics: além de oferecer os serviços básicos para construção de widgets, ele utiliza um modelo orientado a objetos, mesmo tendo sido implementado inteiramente em C. Existem no Intrinsics classes de widgets que se relacionam por meio de herança simples. Todo widget é modelado por uma classe, sendo que existe também o conceirn de classe abstrata. Classes abstratas nunca são instanciadas,

6

Page 20: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

~sl!lfill!·-----· -· - -·--·---~-----t·----·-·- ·· · --·-;

Select • dvi file:

costal tex/ 1 r teJ•/

software/ . .1 ----,.

1 r . . ' .,.

aound:&/ blb/ H•1n.dv1 &w.yl cap@s1 J'' t.•s•/ ftaur•a 111a1n.dv 1

jtex/ 1 gattHS' P'lPO&U/ t.tnp/ prp1

""""'' stiiln/ jtne/ j j

L l testpage .0111

1

file HHlt ~] dot files bidden

Figura 2.2: Diálogo para seleção de arquivos utilizando Athena \Vidget Set

existindo apenas para disponibilizar código e/ou atributos a serem herdados por outras classes.

O tipo mais comum de widget implementado pelo Intrinsics é aquele que não possui outros a ele subordinados; este tipo de widget é por vezes referenciado como widget 7irimitivo (primitive widget). Porém, para permitir um grau mínimo de complexidade na confecção de interfaces gráficas, existem também widgets de composição ( composite widgets).

A mera existência de widgets de composição, no entanto, não oferece ao programador condições sólidas para a implementação de mecanismos para la.yout abstrato. Para este fim específico, o Intrinsics possui os chamados constraint widgets. Trata-se de uma classe especial de lvidgets, derivada dos widgets de composição, que define um conjunto extra de atributos que são herdados pelos seus filhos diretos. Estes atributos são utilizados para armazenar informações específicas para cada filho (por exemplo, tamanhos mínimo e máximo), utilizadas quando há a necessidade de se reposicioná-los ou redimensioná-los.

V\'idgets de composição são utilizados, em conjunto com consfraint widgets, para im­plementar mecanismos de layout abstrato. Existe, por exemplo, o widget denominado Box, que dispõe seus filhos ao longo de uma ou mais linhas. Já o widget Form permite que seus filhos indiquem suas posições relativas ao próprio Forro ou mesmo a outros filhos deste. O posicionamento relativo a outros widgets é especificado apenas como «à direi­ta de" ou "abaixo de" estes outros wídgets, sendo que a distância a ser mantida entre um widget e seus vizinhos é especificada pelo próprio widget. Com relaçã.o ao Form, os widgets podem especificar que devem sempre sei posicionados a uma distância fixa de uma determinada margem deste; podem ainda usar as chamadas "borrachas" (rubbers), que têm suas dimensões alteradas na mesma proporção que o Form, no caso de um redi­mensionamento deste. Existem ainda outros widgets de composição, como por exemplo o paned widget , que é dispõe seus filhos yertical ou horizontalmente; paned widgets são tipicamente utilizados eles mesmos dispostos lado a lado ou uns sobre os outros, existindo entre eles os chamados grips, que são controles que permitem o redimensionamento inte­rativo dos paned widgets. A Figura 2.3(a) ilustra um diálogo com dois paned widgets,

7

Page 21: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

di. postos um sobre outro; na Figura 2.3(b), o gn p foi utilizado para aumentar o paned idge t s perior

. -1-TMailüáiPagC- -- -- ' ' ' - 1

XMAN is an M Window. Syst

G mNG STARTED

By defaul t , xman starts three "buttons" (places t he e buttons, Help and Pase, creat es a new manu button t o open a .new man

(a)

4d 4d60 " Add.-dlsk Bad<.up . cc DCC' IL

XMAN is an X Window Syst

GETIING STAATED

(b)

Figura 2.3: Diálogo com dois paned widgets dispostos verticalmente

A despeito das diferentes políticas de layout implementadas pelos widgets de com­posição, o Intrinsics define uma política global de concentrar as decisões a respeito da posiçào e das dimensões de cada widget no seu pai. Os widgets-filho podem, no máximo, requisitar aos seus pais alterações de tamanho ou posicionamento, mas cabe a estes a de­cisão final: os pedidos podem ser aceitos, negados ou mesmo "negociados", Por negociado entende-se a sit uaçã.o em que o lvidget de composição concorda com uma configuração aproximada do que foi pedido.

No que diz respeito aos eventos, os composite widgets do Intrinsics não possuem suporte direto do too/kit para tratar os eventos antes que estes sejam recebidos por seus filhos. 1 De uma maneira geral, a única maneira de i'v·idgets de composição influirem sobre os eventos destinados a filhos seus é ele ser configurado como "insensível" a eventos, característica que é automaticamente propagada para seus filhos pelo Intrinsics; widgets localizados em uma subárvore configurada como insensível a eventos não recebem eventos de teclado ou mouse.

1\1otif

O toolkit Mot.if (9] é uma alternativa mais sofisticada ao Athena Widget Set, oferecendo widgets de aparência mais rebuscada e "atraente" e em maior variedade - são cerca de 40 widgcts1 de simples botões e text boxes a toggles, listas e menus1 que podem ser combinados de várias maneiras. Existem, inclusive, diálogos pré-definidos para as

1 Isto constitui um grande empecilho à incorporação de widgets Motif a TkVIX, conforme veremos ua S(:ção 3,5.

8

Page 22: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

itua ·ões mais cornun , corno seleção de ar uiv s (a Figura 2.4 mostra o diálogo padrão Motif para sele .ão de rquivos), apresentaçao de informações e consultas ao usuário.

Figura 2 4: Diálogo para seleção de irquivos utilizando Motif

Por ocupar a mesma posição relativa na hierarquia de camadas apresentada na Fi­gura 2.1 que o Athena Widget Set, 1.fotif possui as mesmas desvantages que este: o programador pode se ver obrigado a interagir com todas as camadas para que suas apli­cações funcionem de acordo com o esperado. De maneira análoga, algumas das vantagens do toolkit Athena estão também presentes, como a adoção do paradigma de orientação a objetos e a utilização de constraint widgets para a implementação de políticas de layout abstrato.

A exemplo do widget de composição Forra implementado pelo Athena Widget Set, Motif possui um widget de composição XmForm, onde os filhos são posicionados com relação uns aos outros ou com relação ao próprio XmForm. Embora semelhantes no que diz respeito à sua funcionalidade, o XmForm é, porém, mais flexível do que o Form em alguns aspectos; por exemplo, objetos podem ser posicionados também acima ou abaixo de outros objetos.

Existe também no Motif um widget de funcionalidade semelhante ao Box do Athena vVidget Set; trata-se do XmRowColumn. Seu propósito básico é organizar seus filhos ao lon­go de linhas; porém, melhoramentos foram implementados com relação ao Box. Pode-se, por exemplo, especificar uma direção preferencial (vertical ou horizontal) para o posiciona­mento dos filhos. Outro widget também "aproveitado" do Athena Widget Set foi o paned widget, aqui presente sob o nome XmPanedWindow; de urna maneira geral , os widgets de composição do Athena \Vidget Set estão também aqui implementados) tipicamente com o acréscimo de funcionalidades.

Apesar da complexidade inerente à sua utilização, Motif possui características que fazem dele um toolkit amplamente utilizado na construção de GUis; na verdade, ele tem sido tão utilizado que hoje praticamente constitui uma espécide de padrão: vários outros toolkits procuram conferir a seus widgets o look and feel do Motif.

9

Page 23: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Como característica própria, Motif possibilita a descrição do layout da interface, as­sim como a associação de callbacks a funções definidas pelo programador, através da linguagem UIL ( User Interface Language). Arquivos UIL são compilados em separado da aplicação, resultando em arquivos UID ( User Interface Delinition); estes arquivos é que são efetivamente consultados pela aplicação para a instanciação dos widgets Motif. A interface pode ser, portanto, desenvolvida independentemente da aplicação, facilitando rápida prototipação.

O compilador UIL efetua testes sobre a especificação da interface, emitindo diag­nósticos relativos a situações tais como valores de tipos incompatíveis com os atributos aos quais estão associados, atributos incompatíveis com os objetos a que se referem e impropriedade de relações de "parentesco" entre objetos.

Visando oferecer mais recursos para a criação de interfaces e sua interação com a aplicação, UIL permite a utilização de constantes e de expressões envolvendo inteiros, strings, operadores, constantes, valores booleanos ou números em ponto flutuante. É possível também se criar listas de atributos, widgets ou callbacks e associar nomes a elas, para futura referência. O uso de UIL desobriga o programador de ter que conhecer as funções Motif para criação de widgets, com suas complexas listas de parâmetros.

Motif foi originalmente desenvolvido pela Open Software Foundation ( OSF), pela qual é distribuído mediante pagamento de licenças.2 Hoje, no entanto, existem versões comer­ciais desenvolvidas por outras empresas, assim como versões freeware.

XForms

XForms [28] é um toolkit implementado diretamente sobre Xlib, desenvolvido por pes­quisadores das universidades de Wisconsin-Milwawkee (EUA) e de Utrecht (Holanda). Trata-se, a exemplo do Motif e do Athena Widget Set, de uma ferramenta essencialmente para programadores, uma vez que a definição da interface é feita diretamente em C. Exis­te. no entanto, uma ferramenta auxiliar, denominada fdesign, que possibilita a criação de interfaces de forma interativa; esta ferramenta gera, como resultado final, o código C a ser inserido na aplicação~ restando ao programador gerar o código correspondente às callbacks. Além dos widgets tradicionais (botões, text-boxes, menus etc.), XForms dispo­nibiliza também widgets mais especializados, tais como gráficos 2D e gráficos estatísticos {histogramas, pie-charts etc.). Para visualização de primitivas gráficas, oferece um canvas que provê acesso direto às rotinas Xlib, bem como um canvas OpenGL.

Este toolkit não oferece muitos recursos para especificação abstrata de layouts. Usual­mente, quando um diálogo tem suas dimensões alteradas, os elementos nele contidos so­frem alterações de tamanho e posição na mesma proporção. Alternativamente, pode-se especificar individualmente para cada elemento como este se comportará frente a um redi­mensionamento do diálogo; porém, isto é feito de uma maneira pouco intuitiva, através de restrições à movimentação dos cantos superior esquerdo e inferior direito dos elementos.

A arquitetura em que foi implementado XForms permite a extensão do seu conjunto original de widgets sem que seja necessária a reconstrução do toolkit em si. Embora tenha sido implementado em C, este toolkit oferece suporte a orientação a objetos, com herança

2Formalmente, o toolkit Motif é conhecido por OSF /Motif.

10

Page 24: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

de atributos e comportamento. Existem bindings para linguagens tais como Fortran, Pvthon e Perl, entre outras.

Tk

Tk [18, 17) foi desenvolvido na Universidade da Califórnia (EUA), com o objetivo de possibilitar a criação de GUis utilizando-se a linguagem Tcl (18, 16] e, a princípio, o sis­tema X Windows. Ambos (Tcl e Tk) foram desenvolvidos simultaneamente, pela mesma pessoa. Seu principal diferencial frente aos demais toolkits existentes até seu surgimento, no que diz respeito à funcionalidade, era justamente o fato de ser Tcl uma linguagem interpretada, o que significa, por exemplo, que aspectos da interface podem ser alterados em tempo de execução, ou mesmo que novos widgets podem ser instanciados dinamica­mente. A ausência de necessidade de se compilar uma aplicação Tcl/Tk facilita rápida prototipação. Além disto, Tcl pode ser acoplada a aplicações desenvolvidas na linguagem C; na verdade, a linguagem C é tipicamente utilizada na definição das callbacks de novos widgets criados pelo usuário, embora estas possam ser associadas a comandos Tcl nos casos em que desempenho não é um fator crítico.

Aplicações desenvolvidas em Tcl/Tk possuem à sua disposição um mecanismo para troca de informações mais poderoso do que o tradicional selection (ou cut bu/fer), on­de o usuário, através de comandos específicos (teclado e/ou mouse), coloca informações selecionadas de uma aplicação em um buffer que é compartilhado por outras aplicações, podendo então ser de lá recuperadas por estas; Tk disponibiliza o comando send, que aceita dois parâmetros: o "nome" de uma aplicação e um comando Tcl. Cada aplicação Tk é registrada em uma propriedade especial da root window do dispositivo sob um nome único dentre todas as aplicações Tk sobre o mesmo display. Quando um send é execu­tado, ele localiza a aplicação-alvo através da propriedade da root window e repassa para essa aplicação o comando, através de outras propriedades desta (root window). Um uso interessante para este mecanismo é, por exemplo, um editor de interfaces: em muitos casos, um modelo da interface é editado, isto é, a interface não é testada em situações reais de uso; finalizadas as edições, uma descrição da interface é gerada, devendo então ser incorporada à aplicação para que esta a utilize.3 Utilizando send, um editor desen­volvido sobre Tk pode enviar à uma aplicação comandos para que ela altere aspectos da sua interface durante sua execução, podendo ainda gerar um arquivo com uma descrição da interface a ser utilizada pela aplicação durante sua inicialização. Obviamente, a apli­cação em questão tem de ter sido desenvolvida de maneira a ser capaz de processar estas mensagens.

Tk possui mecanismos para layout abstrato, implementados pelos chamados geren­ciadores de geometria (geometry managers). O mais básico (e o mais utilizado) destes gerenciadores é o packer, que pode ser utilizado para dispor widgets horizontalmente ou verticalmente. Packers trabalham com base nas requisições de tamanho dos widgets a serem posicionados, no tipo de layout desejado e na geometria da janela onde serão posi­cionados os widgets, onde esta janela pode tanto ser o diálogo quanto outro widget. Os widgets organizados por um packer podem ser configurados como expansíveis; espaços (fixos ou expansíveis) podem ser inseridos entre elementos, de modo a permitir maior

3Veremos mais adiante toolkits que possibilitam a edição da interface em tempo de execução.

11

Page 25: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

controle sobre o resultado final. Além do packer, Tk possui também um gerenciador de geometria denominado placer, que posiciona widgets em posições fixas com relação à jane­la (Jayout concreto) ou relativas ao tamanho da mesma; por exemplo, pode-se especificar que a coordenada y de um widget corresponde à metade da altura da janela.

Este toolkit, a princípio, estava disponível apenas para plataformas UNIX baseadas nos sistemas operacionais desenvolvidos pela SUN Microsystems (que é hoje a responsável pela manutenção e evolução de Tcl/Tk), mas hoje já existem versões disponíveis para plataformas Intel/MS Windows, Intel/Linux e Macintosh, com previsões para outras. Todas as versões possuem look and feel Motif.

VisualTcl

VisualTcl (23) foi desenvolvido pela Santa Cruz Operation (SCO). Embora o nome possa sugerir um toolkit nos moldes de Tk, a arquitetura idealizada apresenta aspectos inova­dores.

Um destes aspectos é a utilização de uma arquitetura cliente-servidor. O servidor con­siste de um núcleo gráfico (graphical display engine), que é executado como um daemon: trata-se de um programa Motif, executado em paralelo com as aplicações-cliente, proces­sando, através de mensagens, requisições destas para criar e gerenciar objetos gráficos. Como consequência, interfaces gráficas criadas com este toolkit possuem o look and Eeel Motif. Do ponto de vista do cliente, as aplicações consistem de shells VisualTcl executan­do comandos fornecidos interativamente pelo usuário ou provenientes de scripts VisualTcl e comunicando-se com o servidor para processar as operações relativas a objetos gráficos.

A utilização de uma arquitetura cliente,.servidor traz algumas vantagens: com9 o núcleo responsável pelo processamento das requisições por operações gráficas está localiza­do no servidor, uma vez que este esteja executando, as aplicações-cliente são inicializadas mais rapidamente do que o são aplicações que trazem consigo todo o núcleo gráfico. Além disto, como toda a saída gráfica é tarefa do núcleo, se este utilizar outra biblioteca que não Motif, as aplicações-cliente passarão a apresentar outro look and feel, sem que elas tenham que se adaptar às mudanças.

Além de ser um super-conjunto de Tcl, VisualTcl incorpora também as funcionalidades oferecidas por TclX, uma extensão de Tcl que disponibiliza recursos tais como comandos para depuração, comandos específicos para acesso a serviços do sistema operacional UNIX (envio de sinais, criação de processos, manuseio de arquivos etc.), comandos para acessos a servidores TCP /IP e extensões a comandos Tcl, entre outros.

Os comandos interpretados por VisualTcl se enquadram em duas categorias: comandos Tcl/TclX e os chamados comandos visuais, que são os comandos utilizados nas requisições ao núcleo gráfico. Os widgets acessíveis aos comandos visuais constituem um subconjun­to (extenso, cerca de 90%) dos widgets disponibilizados pela versão 1.2 do OSF /Motif, complementados por alguns widgets extras.

Este toolkit é distribuído juntamente com a última versão do sistema operacional UNIX-like desenvolvido pelo SCO, o SCO Open Server. Neste sistema, VisualTcl foi utilizado na construção das interfaces gráficas para as ferramentas de administração. Além disto, existem versões para outros sistemas UNIX que não o SCO Open Server.

12

Page 26: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Visual Basic

Visual Basic [15] não é exatamente um toolkit para construção de GUis, mas sim um ambiente para desenvolvimento de programas em uma linguagem BASIC-like, que com­preende um editor de código, um compilador, um depurador e um editor de interfaces.

A interface é definida interativamente, via manipulação direta dos objetos pelo usuário: tipicamente, os widgets são arrastados de uma toolbar e posicionados nos diálogos. Um editor de propriedades permite a configuração de características dos widgets. A definição da interface, porém, é permitida exclusivamente na fase de codificação da aplicação; uma vez iniciada sua execução, o usuário final não pode redefinir aspectos da interface, apenas interagir com os widgets de acordo com sua semântica - a menos, é claro, que a própria aplicação seja construída de maneira a permitir este tipo de manipulação da interface em tempo de execução.

Um aspecto interessante deste ambiente é que ele induz à geração de código e interface simultaneamente: durante a definição dos diálogos para interação com o usuário, o pro­gramador pode abrir janelas de edição de código para cada um dos widgets. As callbacks para cada widget já se encontram pré-definidas sob a forma de uma função vazia, ou seja, com os parâmetros pertinentes e sem código algum, cabendo ao programador preencher as que são relevantes para a aplicação em questão. Durante a fase de desenvolvimento, as aplicações tipicamente são executadas a partir do próprio ambiente; neste caso, o código é interpretado, e o programador tem à sua disposição recursos de depuração. Versões stand-alone de aplicações podem ser também geradas, sendo que neste caso o código é compilado para um formato intermediário que consiste de opcodes que são interpretados por uma máquina virtual carregada automaticamente por cada aplicação; aplicações gera­das desta forma não podem ser depuradas. A descrição da interfa.Ce pode ser armazenada em um arquivo-texto, mas o default é um formato binário específico. A criação de novos widgets pode ser feita no próprio ambiente. Aplicações geradas neste ambiente suportam OLE ( Object Linking and Embedding), o modelo da Microsoft para object embedding.

Object embedding é uma técnica através da qual objetos criados por uma determi­nada aplicação podem ser inseridos em outra. A edição destes objetos, porém, é sempre realizada pela aplicação que o originou, e nunca pela aplicação hospedeira (denominada container). As primeiras versões do protocolo OLE estabeleciam conexões não muito for­tes entre o objeto e a aplicação hospedeira. Por exemplo, se um editor de textos possuía uma planilha criada por outra aplicação, e o usuário quisesse editar a planilha, a aplicação que a gerou tinha que ser executada (em uma outra janela), e as alterações repassadas ao editor de textos, após finalizada a edição. Versões mais recentes (OLE2) permitem uma relação mais estreita entre o objeto e a aplicação hospedeira, possibilitando o que se denomina por in-place editting: no nosso exemplo, a planilha seria editada no próprio editor de textos pela aplicação que a gerou.

Não existe suporte para layout abstrato; as posições e tamanhos iniciais dos elementos são definidos quando da criação da interface. O programador tem meios para, durante a execução da aplicação, alterar tais parâmetros, mas decidir quando e como fazê-lo é tarefa sua; existem, no entanto, exceções, como é o caso das toolbars, que são configuradas para se posicionar sempre em uma das bordas do diálogo. Visual Basic permite que a aplicação seja notificada se o diálogo tem suas dimensões alteradas, através de um evento de resíze; com base neste evento, a aplicação pode decidir alterar os parâmetros dos elementos nela

13

Page 27: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

contidos. Visual Basic é um produto estritamente comercial, desenvolvido e comercializado pe­

la Microsoft, e disponível apenas para plataformas que utilizam sistemas MS Windows. Existem outros ambientes semelhantes, que no entanto não serão abordados neste docu­mento, por não apresentarem diferenças significativas a nível da definição/tratamento da interface. Um exemplo é Delphi da Borland Imternational, que embora ofereça um modelo de ambiente para desenvolvimento de aplicações semelhante ao de Visual Basic, baseia-se em uma linguagem de programação diferente (uma variante orientada a objetos de Pascal) e não gera código intermediário, mas sim código de máquina. A interface das aplicações, no entanto, é construída segundo o mesmo paradigma adotado por Visual Basic.

SUIT SUIT [5] foi desenvolvido na Universidade de Virgínia (EUA), com o objetivo inicial de auxiliar os estudantes dos cursos de Informática na construção de interfaces gráficas pa­ra seus trabalhos acadêmicos. Para tal, procurou-se desenvolver um toolkit com especial ênfase na facilidade de utilização (SUIT é composto pelas iniciais de Simple User Interface Toolkit), possibilitando assim que estudantes que não necessariamente possuem familiari­dade com GUis o utilizem - e em muitas vezes para trabalhos em que a interface com o usuário não representa o aspecto mais relevante, o que torna ainda mais crítico dispender o menor esforço possível no aprendizado do toolkit.

As exigências feitas por SUIT são que seu usuário saiba programar em C, e esteja fa­miliarizado com o mecanismo de programação por eventos. O layout da interface pode ser todo especificado em C, podendo também set criado interativamente: embora não p0$8Ua formalmente um aplicativo para especificação interativa da interface, SUIT permite a ma­nipulação dos elementos de interface, no que diz respeito às suas características, durante a execução da aplicação. A posição de qualquer elemento pode ser redefinida através do arrasto do mesmo, por meio da combinação de teclas e botões do mouse. Um editor de propriedades pode ser invocado para qualquer elemento, através de uma combinação de teclas, possibilitando a manipulação de atributos globais, atributos particulares ao objeto ou atributos relativos à classe do mesmo.

A configuração de uma interface é armazenada, ao término da aplicação, em um ar­quivo ASCII. Este arquivo é lido quando da reinicialização da aplicação, implementando, portanto, um mecanismo de persistência. A sintaxe deste arquivo é a mesma de C, para permitir que ele seja incorporado ao código fonte da aplicação, tornando a interface hard coded. Novos atributos podem ser definidos pelo usuário, que deve prover rotinas para conversão do atributo de e para ASCII, para possibilitar persistência, além de rotinas para inicialização, cópia e destruição do atributo.

Novos objetos podem ser criados em tempo de execução através do editor de proprieda­des, embora este procedimento seja efetivamente útil apenas para elementos extremamente simples, que não respondam a eventos do usuário (como, por exemplo, labels). Objetos como botões, por exemplo. não podem ser criados desta maneira, pois mesmo que as funções C correspondentes às callbacks do elemento fossem definidas através de um editor de textos, por exemplo, a aplicação teria que ser recompilada para incorporar o novo widget.

14

Page 28: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

A opção por um toolkit essencialmente didático e destinado a usuários com pouca experiência em programação levou a uma simplificação significativa no seu design. A hierarquia de classes foi limitada a apenas um nível, para evitar que os usuários tivessem que dominar o conceito de herança. Existem atributos relativos aos próprios objetos, atributos relativos às classes de objetos e atributos globais, sendo a ordem de precedência a mesma apresentada: atributos especificados a nível do objeto "obscurecem" os de mesmo nome especificados a nível de classe, o mesmo valendo com relação à classe e o escopo global.4

O suporte a layout abstrato em SUIT é implementado basicamente por widgets deno­minados bulletin boards, que são simplesmente widgets que podem possuir outros a eles subjugados. Os elementos-filho são posicionados com relação ao bulletin board, conside­rando seu canto inferior esquerdo como origem do sistema de coordenadas. Um bulletin board não impõe políticas de layout aos seus filhos, mas estes podem especificar como devem ser posicionados e/ou redimensionados caso aquele tenha seu tamanho alterado, através dos conceitos de molas e barras. Ambos os conceitos se aplicam às direções ver­tical e horizontal, e são empregados tanto entre as bordas de dois elementos diferentes, quanto entre as bordas de um mesmo elemento. Uma mola entre duas bordas indica que a distância entre elas pode variar; uma barra indica o contrário. Existe uma especialização de bulletin boards, denominada stacker, que organiza seus filhos de acordo com a direção vertical ou horizontal. A inclusão e remoção de widgets a um bulletin board pode ser feita interativamente, através de drag and drop.

SUIT é portável para diversas plataforma.s, graças a uma camada criada especialmente para abstrair as particularidades do sistema gráfico nativo. Denominada SRGP (Simple Raster Graphics Package), esta camada possui drivers para sistemas gráficos tais como X Windows e Mac Toolbox (Macintosh), entre outros. Sobre ela pode ser utilizada ainda uma outra camada, denominada GP (de Gra.phics Package), que implementa o conceito de world coordinates e as abstrações de window e viewport.

Segundo seus autores, SUIT é utilizado atualmente em cursos de graduação em Ciência da Computação em outras universidades além da Universidade de Virgínia.

Fresco

Idealizado como uma evolução do toolkit Interviews [14], desenvolvido na Universidade de Stanford no final da década de 80 e início da de 90, Fresco (3, 13] é um framework orientado a objetos para desenvolvimento de aplicações baseadas em janelas, com suporte a distribuição de objetos, multi-tbreading e scripting. Sua arquitetura permite aplicar a objetos visuais as mesmas transformações passíveis de serem aplicadas a objetos gráficos; por exemplo, um botão pode ser rotacionado, e ainda assim permanecer com sua semântica inalterada. Fresco permite também a realização de graphical embedding, que, a exemplo de object embedding, permite a edição in-pla.ce de objetos criados por outras aplicações, mas que, além disso, permite que estes objetos sejam tratados como objetos gráficos

4Com relação à árvore de elementos, onde poderia haver dúvida quanto a de onde herdar atributos (da classe do objeto, do seu pai ou da classe deste), SUIT define a seguinte política: se o atributo não está definido na classe do objeto, ele é procurado no pai do objeto (e não na classe deste) e, em caso de insucesso, nos seus ascendentes.

15

Page 29: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

quaisquer, estando também sujeitos a transformações. Para permitir esta manipulação indiscriminada de widgets e objetos gráficos, Fresco

implementa o conceito de glyphs. Glyph é o tipo fundamental de Fresco, a partir do qual derivam-se especializações - existem os que apenas se desenham, os que desenham decoração sobre outros, glyphs para composição de Jayout abstrato, glyphs que aplicam transformações gráficas e glyphs que lidam com eventos gerados pelo usuário, dentre outros. Este último tipo de glyph, por ser base para todos os widgets que interagem como o usuário (desde botões a diálogos), recebe uma denominação especial, sendo conhecido pelo termo viewer. A existência de um tipo funda.mental (glyph) é que, em última instância, possibilita a homogeneização do comportamento de widgets e objetos gráficos.

A distribuição de objetos é obtida através da conformidade com o padrão CORBA pa­ra objetos distribuídos. CORBA foi definido pelo consórcio OMG ( Object Management Group), com o objetivo de padronizar um modelo para distribuição de objetos. Fresco é CORRA compliant por adotar para a especificação das interfaces por ele definidas a linguagem IDL (Interface Detinition Language), também desenvolvida por OMG. Uma vez definidos em IDL, objetos podem ser implementados em diferentes linguagens de pro­gramação; OMG definiu bindings de IDL para linguagens como C, C++, SmallTalk e Objective C, embora alguns destes bindings ainda se encontrem em processo de padroni­zação. Mediante a utilização do modelo CORBA, objetos podem se comunicar através de uma rede interligando diferentes máquinas.

Fresco possui também mecanismos para composição do layout da interface de maneira abstrata, semelhantes aos utilizados por '!EX (10), com seu modelo de boxes and glue: em Fresco também existem "caixas" ( boxes) que dispõem seus filhos segundo uma deter­minada direção, associada à natureza da caixa. Existem caixas que dispõem seus filhos horizontalmente (hboxes) e aquelas que o fazem verticalmente (denominadas vboxes). A exemplo de 'JEX, Fresco implementa também o conceito de glues, que são "molas" que têm como função separar objetos; glues mudam de tamanho dinamicamente, acompanhando alterações no tamanho do diálogo em que se encontram. Glues crescem de acordo com o tipo de caixa em que se encontram: aqueles situados em hboxes aumentam ou diminuem de tamanho apenas na direção horizontal; os situados em vboxes o fazem na direção ver­tical. Além destes modelos semelhantes aos encontrados no 'JEX, existem ainda outros glyphs de composição, como, por exemplo, tixed grid, que alinha seus filhos de acordo com uma grade, e deck, que exibe apenas um dos seus filhos de cada vez.

Aproveitando-se da capacidade de CORBA de criar objetos dinamicamente, desen­volveu-se um interpretador de comandos baseado na linguagem Tcl, denominado Dish (Dynamic Invocation SHell). Através dele, usuários podem criar widgets interativamente ou através de scripts e associá-los a variáveis Tcl, o que permite, entre outras coisas, rápida prototipação tendo à disposição todos os recursos oferecidos pelo toolkit.

No que diz respeito à portabilidade, a API de Fresco não possui dependências a nenhum sistema gráfico em particular - as peculiaridades de cada sistema gráfico para o qual Fresco possui versão são tratadas, em um nível baixo na arquitetura do sistema, por drivers específicos.

Desenvolvido originalmente como um projeto conjunto entre pesquisadores da Silicon Graphics e da Fujitsu, este projeto contava com a participação de pessoas que estiveram diretamente envolvidas com o desenvolvimento do Interviews, e chegou a constar como

16

Page 30: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

um dos projetos passíveis de serem padronizados pelo X Consortium.5 Em dezembro de 1996, no entanto, o X Consortium retirou seu apoio ao projeto, e seus desenvolvedores se viram desmotivados a manter uma versão pública. Como consequência, Fresco existe hoje apenas como um projeto interno da Fujitsu, sem planos para que haja versões públicas.

2.1 O TeCGraf

O TeCGraf é um laboratório da PUC-Rio com longa tradição no desenvolvimento de sis­temas para atender a necessidades específicas de empresas. Essencialmente, o TeCGraf é o resultado de uma cooperação entre a PUC e a PETROBRÁS, cooperação esta que já existe desde 1985. Ao longo de toda sua história, a questão da interação com o usuário, bem como do desenvolvimento de software portátil para diversas plataformas, sempre ocu­pou lugar de destaque. Além da PETROBRÁS, o TeCGraf possui ainda outros parceiros industriais, como a ELETROBRÁS.

As aplicações desenvolvidas são inerentemente gráficas, dado o tipo de problemas que se propõem a resolver - tipicamente, visualização de massas de dados sob a forma de gráficos 2D e 3D. No princípio, o sistema de interface usado era o INTGRAF [26], e os gráficos eram exibidos através de uma versão do GKS [25) desenvolvida pelo próprio TeCGraf. O INTGRAF, porém, possuía sérios aspectos negativos, sendo um dos mais graves o fato de não permitir uma interação assíncrona entre o usuário e a aplicação. Como resposta a isso, o TeCGraf investiu no desenvolvimento de novos toolkits para a construção de GUis.

IUP

IUP [12) é um toolkit que permite o assincronismo inexistente no INTGRAF e o uso de widgets nativos, além de implementar um mecanismo de layout abstrato semelhante ao de 'IEX e Fresco, com a implementação dos conceitos de hboxes e vboxes, além dos chamados fi.lls, que possuem semântica semelhante aos glues de 'IEX· A interface de uma aplicação que utiliza IUP pode ser definida diretamente em C, mas IUP permite também que a interface seja descrita em uma linguagem própria, chamada LED (Linguagem para Especificação de Diálogos). LED é uma limguagem interpretada que não possui recur­sos procedurais; os arquivos LED são carregados pela aplicação, sem a necessidade de que sejam pré-compilados. Por armazenar apenas a descrição da interface e os nomes das callbacks a serem executadas, o uso de LED permite, a exemplo de UIL (Motif), o desenvolvimento da interface independente do da aplicação. 6

Os widgets de composição têm capacidade limitada de influir nos eventos sobre eles ocorridos: caso estejam desabilitados, nenhum evento será repassado aos seus filhos. Even­tos de teclado podem ser interceptados e alterados pelo elemento correspondente à raiz

50 X Consortium é uma organização sem fins lucrativos que tem como finalidade básica o desenvol­vimento de padrões e tecnologia para sistemas abertos; é responsável, entre outras coisas, pela criação e evolução do sistema gráfico X.

6Embora as duas linguagens possuam esta característica em comum, LED é, no entanto, bem mais simples do que UIL, carecendo de Yários dos recursos oferecidos por esta, como, por exemplo, manipulação de números e booleanos.

17

Page 31: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

da árvore de widgets, antes de serem repassa.dos aos seus alvos originais. Em IUP, este elemento é a própria janela onde são posicionados os widgets, denominada diálogo.

Decisões de projeto tomadas quando do desenvolvimento de IUP levaram à adoção de uma arquitetura não muito modular; a incorporação de novos widgets ao toolkit, por exemplo, não é trivial, exigindo manutenção nos fontes do mesmo.

Existem versões do IUP para DOS, MS Windows e UNIX; uma versão Macintosh está em desenvolvimento. As versões para MS Windows e UNIX possuem como característica adicional o fato de utilizarem widgets nativos (no caso da versão UNIX, widgets Motif). Esta disponibilidade para diversas plataformas constitui uma importante contribuição para a portabilidade das aplicações desenvolvidas no TeCGraf, uma vez que, a menos de eventuais dependências a aspectos específicos de uma determinada plataforma, aplicações que utilizam IUP necessitam apenas ser recompiladas para outras plataformas utilizando­se a biblioteca IUP correspondente. 7

EDG

IUP é a principal ferramenta utilizada na construção das interfaces gráficas das aplicações desenvolvidas pelo TeCGraf; o conjunto de widgets por ele disponibilizado atende às ne­cessidades das aplicações mais complexas. No entanto, no que diz respeito à manipulação de primitivas gráficas, IUP oferece apenas recursos básicos, tais como manipulação de pri­mitivas, monitoração do mouse etc. Não há, por exemplo, o conceito de objetos gráficos, sendo responsabilidade do programador implementar este tipo de abstração utilizando o canvas IUP, caso seja necessário.

Para melhorar o suporte a objetos gráficos, o TeCGraf desenvolveu as biblioteças GLB [21] e Interact (2). A primeira consiste de uma biblioteca C++ que permite a definição de objetos gráficos de modo hierárquico: primitivas gráficas podem ser agru­padas, e grupos podem ser aninhados. Existe também o conceito de clones, que são, a grosso modo, diferentes visualizações de um mesmo objeto, proporcionando economia de memória. GLB permite ainda a descrição/manipulação de objetos através de uma lingua­gem interpretada chamada Lurdes, que é essencialmente uma especialização de linguagem Lua. Interact, por sua vez, implementa o conceito de tarefas (tasks), que são associadas ao canvas e processam todos os eventos sobre ele gerados até que um resultado final, con­dizente com a funcionalidade associada à tarefa, seja produzido, sendo então devolvido à aplicação. Existem diferentes tipos de tarefas: tare/ as de construção, que permitem a criação de novos objetos {linhas, polígonos etc.); tarefas de seleção e transformação, que permitem a manipulação das propriedades de objetos já existentes; e tarefas de visuali­zação, que controlam a área visível do canvas.

A utilização destas três ferramentas tem auxiliado na diminuição do esforço envolvido no desenvolvimento de aplicações com interfaces gráficas com o usuário. Estas ferramentas são acessíveis apenas a programadores, uma vez que constituem bibliotecas a serem utili­zadas pela aplicação. Existe, no entanto, um tipo (cada vez mais popular) de usuário que, mesmo não sendo proficiente em programação, desenvolve aplicações não muito comple­xas, para as quais gostaria de implementar interfaces gráficas, sem que para isto tenha que

7Este passo não necessariamente é trivial, podendo vir a depender de detalhes tais como diferentes versões dos compiladores utilizados, por exemplo.

18

Page 32: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

dominar uma determinada linguagem de programação. Visando atender a esta categoria de usuários, o TeCGraf desenvolveu EDG [8].

EDG implementa abstrações sobre os wiqgets oferecidos por IUP, assim como sobre as primitivas gráficas de GLB; a linguagem Lua é utilizada tanto na descrição do Jayout da interface quanto na descrição dos objetos grádicos a serem exibidos/manipulados - sendo que, no caso de objetos mais complexos, estes podem ainda ser construídos com o auxílio de um editor gráfico específico. Os eventos gera.dos pelo usuário são tratados por EDG no que diz respeito a detalhes, sendo a aplicação notificada em um nível mais abstrato: por exemplo, o conjunto de eventos button down~ mouse movement e button up é repassado à aplicação como eventos de click e drag. Objetos gráficos podem possuir eventos associados a si e tratadores para estes eventos, implementando o conceito de objeto visual ativo -basicamente, a integração de representação e comportamento em uma única entidade.

IUP/Lua Aproveitando-se da experiência de utilização de Lua para descrição da interface obtida com EDG, o TeCGraf investiu no desenvolvitnento de um binding de IUP com Lua, para possibilitar que a construção de diálogos pupesse ser feita inteiramente nesta linguagem.

Conforme já mencionado anteriormente, Lua é uma linguagem de extensão desen­volvida no TeCGraf. Linguagens de extensão (extension Janguages), também conhecidas por linguagens embutidas ( embedded Janguages), tipicamente possuem recursos tais co­mo definição de funções, controle de fluxo, loops e binding com outras linguagens; não é incomum oferecerem também o recurso de tipagem dinâmica. Estas características, em conjunto com o fato de serem em grande parte dos casos linguagens interpretadas, as tornam extremamente atraentes para rápidia prototipação e utilização por usuários com pouca experiência em programação - embora, em alguns casos, a sintaxe utilizada pela linguagem represente um obstáculo à sua utilização por esta classe de usuário; Tcl seria um exemplo típico. Como exeinplos de linguagens de extensão, podemos citar, além de Tcl, a linguagem Pyhton [27].

Algumas das características de Lua mostram-se especialmente úteis na sua utilização para criação de interfaces gráficas de aplic~ções IUP, em contraste com a maneira tradi­cional (interface em LED ou C, aplicação em C); são elas:

• trata-se de uma linguagem interpretada;

• possui ti pagem dinâmica, além de um poderoso (ainda que de simples utilização) mecanismo de arrays associativos;

• sua sintaxe simples, aliada aos recur5os procedurais disponíveis, permite que não apenas o layout da interface seja descrito em Lua, mas que também algumas das funcionalidades da aplicação sejam implementadas diretamente em Lua, se isto se mostrar adequado;

• pode ser facilmente integrada a progtamas C/C++;

• embora não seja inerentemente orientada a objetos, Lua permite a implementação de diferentes mecanismos de herança, de atributos/funções.

19

Page 33: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Todo widget disponível em IUP possui u1111a classe correspondente em IUP /Lua, assim como uma função de criação específica (construtor). Estas classes foram organizadas de acordo com uma hierarquia, com a finalidad~ de propiciar herança de código. 8

Cada widget instanciado em IUP /Lua é $.rmazenado como um array associativo, que em Lua é modelado pelo tipo tabela. Todos os atributos pertinentes a um determinado widget estão presentes na tabela correspond~nte IUP /Lua sob a forma de campos desta. O mecanismo de fallbacks de Lua (apresentado na Seção 3.1) permite que alterações em atributos associados a números ou strings sejam imediatamente repassadas a IUP, resultando em um feedback visual imediato.

A utilização de IUP /Lua traz ainda outras vantagens, além das mencionadas ante­riormente; uma delas é o fato de que widgetls que serão associados a atributos de outros w.iidgets (como, por exemplo, o menu de um ctliálogo) não precisam ter um nome explicita­mente a eles associado. Caso não tenha sido especificado um nome, IUP /Lua se encarrega de criar um e associá-lo ao widget; este nome será utilizado daí por diante em futuras associações a outros atributos. Em LED isto não é possível: um objeto tem que ter sido previamente associado a um nome para poder ser associado a um atributo de outro objeto. Outra vantagem decorrente da utilização de IUP /Lua é o fato das callbacks associadas a eventos gerados pelo usuário serem automaticamente associadas pelo toolkit a métodos dos objetos; com isto, o programador pode escrevê-las diretamente em Lua. Se houver necessidade de implementá-las em C, cabe ao programador registrá-las previamente em Lua, associando-as aos atributos pertinentes.

2.2 O Framework VIX

Conforme visto no início deste capítulo, muitos dos toolkits existentes não são construídos diretamente sobre o sistema gráfico nativo, utilizando-se de camadas de software que têm por função abstrair detalhes do mesmo; podemos identificar esta característica em todos os toolkits construídos sobre o Intrinsics, e mesmo em alguns que não o são, como, por exemplo, SUIT. Vimos também exemplos de toolkits que são construídos diretamente sobre o sistema gráfico nativo, como é o caso de XForms, construído diretamente sobre Xlib.

Toolkits com esta característica de não estarem implementados diretamente sobre o sistema gráfico tendem a ser mais simples, do ponto de vista da implementação, do que aqueles que não a possuem, por não ter que lidar com os detalhes associados à criação de objetos gráficos. Além disto, o fato de existir uma camada entre o toolkit propriamente dito e o sistema gráfico nativo pode representar um significativo aliado na busca por uma maior portabilidade dos toolkits, uma vez que as modificações necessárias para se portar um toolkit para um determinado sistema gráfico podem se concentrar nesta camada, evitando (ou, pelo menos, minimizando) manutenção no toolkit.9

Visando simplicidade, modularização e portabilidade, o toolkit TkVIX foi criado sobre um framework implementado em C++, denominado VIX (7). Além de contribuir para

8Utilizou-se para implementar herança simples em Lua o mecanismo descrito no manual da linguagem; este mesmo mecanismo é descrito na Seção 3.1

90 fato de existirem camadas intermediárias entre o sistema gráfico nativo e o toolkit não implica necessariamente em maior portabilidade: o lntrinaics, por exemplo, é usado apenas com Xlib.

20

Page 34: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

conferir a TkVfX as características mencionadas, V1X cumpre o fundamental papel de prover suporte à utilização de objetos visuais ativos.10 Para tal, uma série de conceitos são implementados:

objetos visuais (ou VOs, do inglês Visual Objects) são objetos gráficos que reagem a eventos e/ou possuem comportamento próprio; VIX disponibiliza um tipo básico de VO, que pode ser derivado para outros V Os mais específicos, através do mecanismo de herança de e++.

espaços visuais (ou VSs, de Visual Spaces) modelam as superfícies de visualização onde são posicionados os VOs; é através do VS também que o VO recebe os eventos gerados pelo usuário. Um VS possui, por definição, um único VO; cada VO, por sua. vez, está associado a um único VS.

filtros são entidades idealizadas para serem dispostas entre VOs e VSs, podendo alterar ou suprimir eventos gerados no sentido VS ~ VO ou requisições feitas no sentido VO ~ VS. Para tal, filtros são implementados como derivações de VS e VO, simultaneamente, de maneira que possam ser enxergados como VS por um VO e vice-versa.

flllro ,--... --------------.. 1

' 1 • · 1 ~-----1- vo ' -·------' 1

1 1 , ___ _____ _________ ,

__ ... __ __ _ __

Figura. 2.5: Filtros em VIX

O filtro defauJt do framework é o mais básico possível: um filtro inócuo, ou "trans­parente,,, onde eventos e requisições são repassados na íntegra, sem alterações. Especia­lizações podem ser construídas a.través de herança sobre esse filtro básico. Filtros podem ser "subjugados" a outros filtros, isto é, filtros podem ser encadeados, tendo como resul­tado um efeito cumulativo: um evento, ap6s ser processado pelo n-ésimo filtro de uma cadeia, acumula em si os n processamentos sofridos, na ordem em que ocorreram. Existe um tipo de filtro, já pré-definido no framework, de utilização bastante ampla: trata-se do grupo , que nada mais é do que um multiplexador. Através dele, vários Vüs podem ser subjugados a um único VS. O grupo é enxergado pelo VS em que se encontra como seu único VO, e os VOs a ele subjugados o enxergam como seu VS.

Gtupos podem, de acordo com a natureza do evento a ser repassado aos V Os, selecionar aqueles que o receberão, nos casos em que isto for relevante para o desempenho do sistema. Um exemplo típico é o evento de repa.int, cujo tratamento é detalhado na Seção 3.2.2.

1ºNa verdade, oferecer suporte ao desenvolvimento de aplicações que utilizam o conceito de objetos vi!uais ativos constitui o propósito fundamental de VIX.

21

Page 35: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

• vs

o -A o vo

-- grupo

o

- o o

ó modefo conceituai adotado p.ór VIX baseia~sé fõrtementé no· implementado,. por 'UAI [6}~ este. taip~w; 4e qµi fi.'~~w-0r.k p~a suporte ·~ pbjeto~ 'vi$U:ai~ qu~ ~;rµpleqi~nt~ -0s c<>nteitOS. de· VO, YS ce fitt_rus.

Embora VIX possíbllité à. mâllipul~io de· obJetos: :gtáfi.cos, ele não ;é tespónsáv.el diretamel,lte pelo g~enciamento das, primitivas gr4fic~{i para isto ele faz uso dos· .se~ç~ diSponlbílizados · pot" mna bibliotec~ ;<\enonúnada · Oanvsis Dtaw (CD.) 1 d.~nv.:alt.ida no 'TeCGraf dê modo a. permitir niálirpula.çao dé. primitivas :grá.ll~1 abstraindo do. 'Usuáiío· o '.$istema gráflco· JJ.átivQ que· se~ encontra .sób á mesth~. n Existém verSões do ·~on para :X Wiµd.ow~·i MS Windows, MaciJ)tQ&U, e ª1W m~.o. MS-00$;: ·o .que. g~r.@te..<que.;1 fiq 11rmt9 de vistq. dg. 1'tili.;aç4a; da~ ·rCéutsQft: gráficos, as' apll~çõ.es. qu~: µtilizam Q OD :são p:Ptiável!:1·' . . Pata. emas pla~a!onnas.

A ligação CD ~ VIX. 'é: feita através do conceito de: dispositivo: toda: primitiva grá:fic.~ .é ~ééµt;ada pot VIX,. em_ úl.twr~ J$~~êÍÀ, so~te :um ,dí~p~iti'79 (c~d~ VS, ~tá: àSSô.éíad~ a um <disp_ositívõ CD). ·O an disponibillza, váriõS, ·tipos de.âispMitivõ1 Sel'ido~ Q:

mais utilizado-o window de.vice~ .. que representa .umajanela da sistema gráfico nativo. Den­'tre 0utros :<\ispositiv~ dispopjvei.~i pqdemos cit.ar P.osts.pript,. 'CG l\{ ( Q.o.zp:pt;,,te.r· GJ:apJ;1fc~ Metafile). i~ lUP C8.tlV$;,

A. lêm ide. ne itif: a. á · lfoa~"i'\ de · ti · "t;: · a•1 ... i.c . · ·di ~m+i os .. CD · é . ·'tem · dá _ . .. .t' nn . . p . ·- '!i-.0· . . p m1 ...... vas. O"C),ucas,. sp"""'" v _ p lllll.l. a.m . _ () gerenciamento de atributos tais como ~or, estil9s· de linha) padrões d~ pree~düiµento ~te.~ çerc:eam~nto {clippip.g)i tr.anÃ.fon:naçõe$ ,d~ cQ!Prde.nadas e ·t.r~;cnen.to. de 5ínagen.s.~

Um dos. princípio.s que nó1,'teàrã.m o· d~nvolv-imenta .de V.XX iol.:CJ de prQéurà.r fái.ê~· lo da forma ma.is simples possíYel, de· .modo a ·não sobrecar.regá .. Io com -funcionalidades: ú.~~ -apenas-em ça$OS e.sp.eeffitQS, que teriam. :que ·~r inçorpox~as· pllr todas '® a_plic:ações :que o utHí.Za$em. Porém, ao. deé;ldfr-~ pél~ ;símplidcfade;: ,cwdôÚ-se também ,Pará. que. ·o framework fosse: suficientemente fleJCÍvelt de modo que .as aplicações ~ue .efeti~mente . .u~essítem de. funcionª1idades· ~ e$p.ecµi~~ do qu.e· M .·. ~twnihiliz~as: pelp li:an:ie~work' pos.sam impleme.ntá-1as:sem d~pend~r imüto. esfor90' nesta táreia. Um recurso empregado por· VDC que. :possui· grande importância para. sua iJ,exibilidaqe é: .ó. Jl}eç~xpp d~ tr.oc.a d~

11 Conforme veremos. mais: adiante~ .o framework utiliza na verd~e: uma. ver$âo do C.D que: :Ilda nâo :apenas çóm pt.~tiva.s gráfi.caa., ~ t~b~ ~ ~Vf.P~i ~a.ta-~~ :d,o. CD ,tan,dajq~~.

22

Page 36: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

PostScnpt

· · · dispositivos

window

0101101010

'-~ 1011101011

011 1010001

CGM

Figura 2.7: Dispositivos em VIX

mensagens; através dele, dados são envia.dos de/para objetos, que os processam por meio de tratadores (handlers). Isto permite, por exemplo, que objetos com comportamento bP-m mais especializado do que o previsto pelo framework comuniquem-se através de mensagens tão complexas quanto seja necessário - o framework apenas se encarregará. de transportá-las, independente do seu conteúdo/propósito; a decodificação destas mensagens é encargo dos handlers, que são implementados pelos próprios objetos envolvidos na troca de mensagens - contribuindo assim para que o framework não tenha que se adaptar a novos tipos de objetos que sejam criados. O mecanismo de mensagens é apresentado em mais detalhes na Seção 3.4.1.

:..3

Page 37: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Capítulo 3

O Toolkit

A exemplo do framework, decidiu-se basear o desenvolvimento do toolkit TkVIX no para­digma de orientação a objetos. Porém, ao contrário daquele, que foi desenvolvido em C++, optou-se por utilizar neste não uma linguagem de programação convencional, mas sim a linguagem de extensão Lua; esta escolha foi norteada por características da própria lingua­gem, características estas apresentadas ao final da Seção 2.1. Em particular, recursos como tipagem dinâmica e arrays associativos serão de grande utilidade na criação/manutenção dos atributos dos widgets do toolkit.

3.1 A linguagem Lua

Lua é uma linguagem interpretada, idealizada para ser utilizada como linguagem de con­figuração por outros programas. Devido a esta característica, Lua não possui em si o conceito de "programa principal"; sua implementação se dá sob a forma de uma bibliote­ca a ser ligada aos programas, que passarão~ então a poder executar código Lua, armazenar e recuperar valores em/de Lua e até mesmo cadastrar funções escritas em C para serem executadas por Lua.

Uma das características mais atraentes ~e Lua, por ter um significativo impacto na faci­lidade de uso da linguagem, é o fato de ser ela dinamicamente tipada. Em Lua, as variáveis não são tipadas, os valores que elas arm~nam é que o são. Existem sete tipos básicos: números com ponto fiutuante (number), strings (string), funções (function), funções e (CFunction), um tipo especial para ponteiros C armazenados em Lua (userdata), um tipo especial associado tanto à ausência de valor quanto ao valor lógico falso (nil), e tabelas (table).

O tipo function é associado a funçõE!S implementadas diretamente em Lua; o tipo CFunction a funções implementadas em C registradas em Lua, o que as habilita a serem executadas pelo interpretador. O tipo u$erdata permite o armazenamento de valores arbitrários de C em Lua, sob a forma de ponteiros void; este recurso é explorado pelo toolkit quando se faz necessário manipular objetos gráficos criados diretamente em C, conforme veremos na Seção 3.4.1. Por fim, o tipo table modela arrays associativos, isto é, arrays que podem ser indexados não apE1nas por números, mas sim por qualquer objeto; isto permite ao programador manipular estruturas de dados complexas como tabelas de símbolos e conjuntos de maneira simples e intuitiva.

Page 38: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Tabelas devem ser explicitamente criadas antes de serem usadas. A criação de uma tabela se dá através da utilização de chaves ( { e } ) , sendo possível a inicialização de campos da tabela no momento da sua criação. Na inicialização dos campos de uma tabela, o conjunto de campos associados a índices numéricos é separado dos campos associados a nomes por um ponto-e-vírgula. Por exemplo, a atribuição

tab = {"abc", 54; other = {}, f2 ="texto ... "}

cria uma tabela e a associa à variável tab, designando valores para os seguintes campos: tab[1] = 11 abc 11 ,tab[2] = 54,tab["other"] éumaoutratabela(vazia)etab["f2"] = "texto ... ". Como uma alternativa à utiliz~ de tabelas como arrays, estas podem ser também acessadas como registros, através da sintaxe tabela. campo, que é internamente traduzida pelo interpretador para tabela[ 11 ~ampo 11 ]. Assim, no exemplo anterior, tab. f2 possui o valor "texto ... ". Referências a campos não inicializados não incorrem em situações de erro, simplesmente retornam o valor nil.

Tabelas são largamente utilizadas na implementação de TkVIX: todo elemento de interface criado a partir da descrição em Lua da mesma é armazenado sob a forma de uma tabela.

A linguagem Lua possui um poderoso mecanismo de fallbacks, que possibilita aos pro­gramadores estender a semântica da linguagem de maneiras pouco convencionais. Fall­backs são funções chamadas por Lua quando o interpretador não sabe como proceder frente à uma situação de erro. A princípio, cada situação de erro possui um tratamento default, tipicamente a exibição de uma mensagem de erro seguida pelo término do progra­ma. Várias situações de erro estão associadas a fallbacks específicas, tais como operações aritméticas entre valores não-numéricos, acesso a variáveis não-inicializadas e acesso a índices ausentes em tabelas.

Uma das possíveis utilizações de fallbacks é a implementação de mecanismos de he­rança na linguagem. No caso qe TkVIX, empregou-se fallbacks na implementação de um mecanismo de herança simples, de modo a viabilizar a implementação do toolkit segundo um paradigma de orientação a objetos.

Apresentamos a seguir o trecho de código responsável pela implementação do meca­nismo de herança simples em Lua:

function Index(t, f) if f == 1parent 1 then

return Oldlndex(t, f) end local p = t.parent if type(p) == 1table' then

return p[f] els e

return Oldlndex(t, f) end

end

A redefinição de fallbacks para rotinas criadas pelo usuário é efetuada pela função Sietfallback. Ao ser executada, setfallback recebe como parâmetros a fallback a ser

25

Page 39: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

substituída e a função substituta, retornando a função originalmente associada à fallback em questão, para futura referência. SendQ assim, a implementação do mecanismo de herança simples é completada pela instrução

Oldlndex = setfallback( 11 index 11, Index)

A função Index é, portanto, associada à fallbaek de índices, o que significa que sempre que for feito um acesso a um campo inexistjente em uma tabela (seja ele um atributo ou o um método), Lua chamará esta função, passando como parâmetros a tabela e o campo em questão. Caso a. tabela possua um campo parent (indicando a classe da qual ela é herdeira), o mesmo campo fé acessado na tabela indicada por t .parent. O processo se repete até que o campo seja efetivamente encontrado ou a tabela em questão não possua um campo parent; neste caso, a fallback original {armazenada em Oldlndex) é chamada para prosseguir com o tratamento default dia linguagem.

É interessante observar que este mecanismo não possibilita controle quanto à acessibi­lidade de atributos e métodos de uma deterII!linada classe por métodos de outra classe (não necessariamente derivada desta), ou mesmo por funções globais da aplicação. Comparan­do com C++, por exemplo, não há um paralelo com o controle de escopo proporcionado pelos qualificadores private e protected.

Além dos recursos mencionados acima, aplic~ões Lua em fase de desenvolvimento podem ser ligadas a uma biblioteca que acrescenta comandos de depuração à linguagem. Lua permite ainda chamadas ao sistema operacional, e possui um poderoso mecanismo para casamento de padrões (pattern matcbing).

3.2 Hierarquia de classes

Tendo implementado o mecanismo de herança simples apresentado na Seção 3.1, criou-se em Lua uma série de classes, para modelai> os diversos widgets a serem implementados. Algumas destas classes são abstratas, isto 'é, nunca serão instanciadas, servindo apenas para disponibilizar código a ser herdado por outras classes (desempenhando, portanto, um papel análogo ao das classes virtuais puras em C++).

Na Figura 3.1, apresentamos a hiera.rquila de classes implementada em Lua. As classes abstratas estão diferenciadas por uma borda tracejada.

Dentre as classes criadas, existem aquel~ que têm como função modelar os elementos de interface ( widgets), implementadas somente em Lua; outras correspondem a classes existentes no framework, de modo a propiciar um mapeamento destas em Lua, consti­tuindo o binding entre as camadas C++ e Lua do toolkit (ver Seção 3.2.2).

3.2.1 Widgets

Com o objetivo de testar-se aspectos do toolkit tais como suporte a Jayout abstrato, utilização dos conceitos de VO e VS na construção de elementos de interface e herança de código Lua para implementação de novos widgets, implementou-se um conjunto básico de widgets, definidos apenas em Lua sobre os conceitos de VO e VS implementados pelo framework. Este conjunto de wídgers consiste de:

26

Page 40: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

' : VlxTypeLueVO '

----------- ... ' ' : YlxTypelulVS :

~~ -_ ~--~ r_~ ~~-:-, -----r---

,- -...... --'

: WIDGET: ' '

VllTypeLulWIMDw :

---~---·

RBUTTON

.---- ............................... -, : VlxType11d.ueOraup : ·-------r-------,.

___ 1 ........ , : QR(>UP :

---~--------

HORMENU

i_T_j

EJ Figura 3.1: Hierarquia de classes em Lua

Dialog - modela a janela em que serão posicionados os demais. widgets; possui apenas um filho;

Hbox - elemento de composição que distribui a quantidade de espaço horizontal recebida do seu pai entre seus filhos, de manei~a que estes sejam alinhados horizontalmente, tendo seus tamanhos mínimos e máximos respeitados;

Vbox - elemento de composição semelhante ao Hbox, com a diferença de que aqui os filhos são alinhados verticalmente;

Fill - elemento expansível, que tem coµto finalidade modelar o conceito de "molas" a serem inseridas entre os elementos,, de modo a facilitar a descrição abstrata de um layout; B.lls são expansíveis apena$ em uma direção, determinada pela natureza do seu pai: um fi.11 se expande na diteção horizontal se se encontra em um hbox, e na vertical se seu pai é um vbox; ~u comportamento default é absorver espaço indefinidamente, possuindo um tamanho inicial nulo;

Button - modela widgets do tipo push button (ver Figura 3.2(a)). Possui aparência 3D, que é alterada quando o botão do mouse é pressionado sobre ele. O usuário pode especificar uma ação a ser executada nesta situação; esta ação pode consistir simplesmente do nome da função a ser executada, embora o programador possa especificar alternativamente uma lista de ações sob a forma de uma string. As vantagens e desvantagens de se utilizar uma ou outra abordagem são discutidas na Seção 3.3.2.

27

Page 41: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

RButt on - emelhante a Button, com a mie diferença de possuir geometria circular (v r Fi ur 3.2(b)) ;

botao

(a) (b)

Figura 3.2: Botões implementados no toolkit

Label - modela textos estáticos, que não respondem a eventos do usuário;

Canvas - elemento que atua como espaço visual para outros elementos, sem, no entanto, impor a estes nenhuma política de layout. Possui uma cor de fondo própria e é expansível em ambas as direções;

Item - item de menu; consiste basicamente de um Label sensível às callbacks de enter, leave e button press. Tipicamente, possui como pai um elemento da classe HorMenu, descrita abaixo;

HorMenu - modela menus horizontais. Por ser derivado de Hbox, aceita como filhos, além de elementos da classe Item, fills, que podem ser utilizados ·para determinar espaçamentos entre os itens do menu.

Por ser subclasse de Hbox, um menu horizontal pode ser filho de um grupo qual­quer, e nào apenas da janela principal; isto permite aplicar a ele tratamento pouco convencional para menus, inserindo-o em qualquer ponto da árvore de widgets, onde ele será encarado como um grupo. Um exemplo desta versatilidade é ilustrado nas figs. 3.3 e 3.4. Observar, na Figura 3.3(b), o efeito da utilização do flll para obrigar o menu a ocupar todo o espaço horizontal possível.

Alguns destes widgets possuem particularidades que enriquecem os recursos por eles oferecidos. Ambos os tipos de botões, por exemplo, permitem Iabels com mais de uma linha de texto, conforme ilustra a Figura 3.5.

Já hhoxes e vboxes possuem um atributo cuja função é especificar o alinhamento dos seus filhos; trata-se do atributo alignment. Para hboxes, alignment pode ser associado aos valores TOP (default), CENTER e BDTTOM. O impacto da utilização deste atributo sobre liboxes pode ser visualizado na Figura 3.6.

Para vboxes, os valores podem ser LEFT (defa.ult), CENTER ou RIGHT. A Figura 3.7 ilustra o impacto do atributo alignment sobre vl>oxes.

A utilização do atributo alignment pode poupar a utilização de fills e grupos na especificação de determinados layouts; a Figura 3.8 mostra a árvore de elementos associada ao diálogo exibido na Figura 3.7(b), em comparação com a que seria necessária. para se obter o mesmo diá.logo caso não fosse utilizado o atributo alignment (isto é, caso ele possua seu valor default).

28

Page 42: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

dialogo

(a} (b)

""igura 3.3: Exemplos de ompos \oes possíveis com menus

-----~-~ ~ - . -~ r--r···------ -- -- --- ------ . ----- -·- 1

Menus ! 1 1

Item ltum J

Item Item

(n) (b)

Ftg ura 3."l: Dialogos resultante; 1las 1 sprcificações da Figura 3.3

1. Buttons • l - - 1

f igura. 3 5: Botões C'Orn lil>el. de mais de uma linha

29

Page 43: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

-~t -- Hllox ali!Ji~ment - l r r 1 ! 1 Hl.lox a1Ígnme11t f 1 • 1 r- • · Hbox alignment ] r ! i [

(a) alignm nt = TOP (b) alignm nt = CENTER (e) alignment = BOTTOM

Figura 3.6: Impacto do atributo alignment em hboxes

- -v11ox aJigr~ment ~I , r • + Vhox alf9nrnent • • - : ! r Vbox alignment 1 • 1 i 1

aliel

MudJ bÍ9!Fr Iabel

(a) alignment = LEFT (b) alignment = CENTER (e) alignment = RIGHT

Figura 3. 7: Impacto do atributo alignment em vboxes

Em TkVIX, a especificação da interface ê feita diretamente em Lua. No momento da instanciação de cada widget, .deve ser caracterizada uma relação de "parentesco" com al­gum outro widget, que deve constar corno pai do widget em questão (o único elemento que não precisa possuir outro widget na condição de pai é o diálogo); isto é feito basicamente para que se possam estabelecer, no nível do framework, as relações entre os VOs e VSs correspondentes aos elementos de interface. Como consequência direta desta imposição, o primeiro widget a ser instanciado é sempre um diálogo. De maneira análoga, widgets de composição devem ser instanciados antes que objetos sejam a eles agregados.

Estas relações de parentesco entre os widgets resultam em uma hierarquia dinâmica, à qual chamaremos simplesmente de árvore ao longo do documento. Observar que esta hierarquia não é a mesma existente entre as classes dos widgets, à qual nos referiremos por hierarquia estática, ou simplesmente hierarquia.

A convenção adotada em TkVIX para se especificar o parentesco entre widgets é: o campo de índice 1 (um) da tabela associada a um determinado widget deve conter o widget do qual ele é filho. Os atributos dos widgets correspondem .a campos das tabelas dos mesmos. Como exemplo, um ,diálogo que contém apenas um botão em seu centro teria a seguinte descrição em TkVIX:

dlg = Dialog {vidth = 140, height = 100t title = "Dne button11}

vl = Vbox {dlg} Fill {vl} h1 = Hbox {vi}

Fill {v1}

30

Page 44: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

GJ (a) alignment = LEFT {default)

diálogo

(b) alignment = CENTER

Figura 3.8: Simplificação da descrição do diálogo 3. 7(b) através do uso do atributo alignrnent

31

Page 45: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Button {hl label = 11 End 11 button_cb = exit} Fill {v l}

Fill {vl}

A arYore associada ao exemplo acima po le ser 1isualizada na Figura 3.9(a), e o diálogo rrsult ante pode ser Y1~uahzado na Figura 3 9 b).

diálogo

-; · · one bÚtton-f ,-Tr

(a) ôrvore {b) diálogo

Figura 3.9: Diálogo simples contendo apenas um botão

Para melhor compreensão do exemplo. cabe uma explicação a respeito da sintaxe permitida por Lua para inicialização de tabelas através de funções: em Lua, o identificador de urna função seguido de uma tabela representa a. execução desta função tendo como único argumento a tabela em questão. No 11osso exemplo, a linha

Button {hl; label = 11 End 11, button_cb = exit}

representa a execução da função Button tendo como parâmetro mna tabela com os atri­uutos do novo botão a ser criado:

Button({h1; label = 11 End 11, button_cb = exit})

A função Button, no seu papel de construtor , recebe a tabela, realiza testes de con­sistência (como, por exemplo, verificar se foi indicado um widget-pai), inicializa atributos relevantes que não estejam presentes (como, por exemplo, largura e altura, de acordo com o Jabel do botão), executa o construtor da superclasse e cadastra o botão como filho de ~eu "·idget-pai, para então retornar uma tabela apta a ser utilizada pelo toolkit; esta tabela pode ou não ser armazenada em uma variável, para futura referência. O procedi-· mento é análogo para os construtores dos demais widgets. É interessante observar que os testes realizados pelos construtores, em conjunto com os testes sintáticos e semânticos executados pela própria linguagem, assim como a possibilidade de se associar valores a variáveis, fazem com que Lua desempenhe o mesmo papel que UIL, no que diz respeito a críticas à descrição da interface.

32

Page 46: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Através desta instanciação de um botão, podemos também perceber a utilização da siuta.xe de Lua para especificação simultânea do widget-pai do botão (no caso, o 11box h 1) e dos atributos deste. Neste exemplo, em particular) associamos a função exi t de Lua à callback do botão, o que faz com que o pressionamento deste encerre a execução da aplicação. A indentação utilizada não é obrigatória, constituindo apenas um recurso visual para representar os níveis de aninhamento da interface.

Este exemplo, embora simples, evidencia a importância do layout abstrato: a combi­nação de vboxes, hboxes e fills foi feita, neste caso, de modo a garantir que o botão vá sempre ser exibido no centro do diálogo, mesmo que este mude de tamanho, estando a aplicação isenta de gerenciar o posicionamento do botão. Diálogos de complexidade mais elevada são apresentados como exemplo na Seção 3.3, onde descrevemos o algoritmo de layout abstrato.

Uma das características de TkVIX com relação aos widgets é que, de uma maneira gc~raL estes podem possuir tamanhos mínimos e/ou máximos especificados pelo usuário. Normalmente, os n·idgets já possuem um tamanho mínimo, calculado de acordo com sua natureza; por exemplo, o tamanho mínimo de um botão é calculado em função da string a ser exibida como label. Porém, o default é o tamanho máximo ser igual ao mínimo, o que, na prática1 implica no widget possuir tamanho fixo. O usuário pode, através de atributos, especificar um tamanho rrniximo para os objetos, que passam, portanto, a poder absorver espaço além do mínimo que lhes será fornecido, assumindo a condição de elementos expansíveis . Dentre os widgets implementados por TkVIX, apenas o canvas e o flll são .. por default, expansíveis. O tamanho máximo de um objeto pode ser associado à constante INF, caracterizando ausência de limite máximo. Na Figura 3.10 podemos ver um exemplo de widgets configurados como expansíveis.

(a) (b)

Figura 3.10: Exemplo ilust1 ando a expansibilidade dos widgets

Outra característica com relação aos w1dgets é a de ser possível atribuir prioridade ao elemento , prioridades estas que serão consideradas quando da distribuição de es­paço (element os com prioridade mais elevada t ~ m precedência na distribuição frente ao demais). O pro esso de distribuição de e p ço ' det alhado na Seção 3.3.

13

Page 47: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

3.2.2 Binding com o framework

As classes relacionadas na tabela 3.1 constituem o binding da camada Lua do sistema com a camada C++. Em seus construtores são executadas funções C++ previamente registradas em Lua que têm como tarefa criar um objeto C++ da classe em questão e amarrá-lo ao objeto Lua que está sendo criado, através da atribuição do ponteiro C++ a um campo do objeto Lua. Com isto, cada objeto Lua tem uma referência para o objeto correspondente criado em e++, que é utilizada sempre que um método e++ deve ser executado por um objeto Lua.

De uma maneira geral, cada método de cada uma das classes relacionadas na segunda coluna da tabela 3.1 possui uma função correspondente registrada em Lua; eventualmente, alguns métodos e++ cuja funcionalidade diz respeito a aspectos internos podem não ter correspondente em Lua. Quando um método Lua é executado, tipicamente o que acontece é apenas a execução da função C++ correspondente, com a passagem do próprio objeto como o primeiro parâmetro, sob o nome self; através deste parâmetro a função C++ tem acesso ao objeto Lua que originou a chamada e, consequentemente, ao ponteiro do objeto C++ correspondente, e seu método pode então ser executado.

Lua e++ VixTypeLuaVO VixTypeVO VixTypeLuaVS VixTypeVS

VixTypeLuaWindowDvc VixWindowDvc VixTypeLuaPsDve VixPSDvc VixTypeLualmgDvc VixlmageDvc VixTypeLuaWindow VixLuaWindow VixTypeLuaGro~ VixLuaGroup

VixTypeTkLuaCan~as VixTkLuaCanvas

Tabela 3.1: Mapeamento de classes C++ para Lua

Esta comunicação intensa entre C++ e Lua pode, se mal administrada, vir a ser um aspecto negativo considerável no desempenho do sistema. Nosso objetivo é construir um toolkit para interação gráfica com o usuário; embora queiramos realizar parte do proces­samento do toolkit em Lua, sabemos que a velocidade de resposta do sistema aos eventos gerados pelo usuário final ou àqueles gerados pelo próprio sistema gráfico nativo (repaint, resize etc.) deve ser aceitável. Por aceitável entende-se uma resposta que não implique em retardos perceptíveis pelo usuário. Este conceito pode ser melhor compreendido com o auxílio de um exemplo.

Um exemplo crítico é o evento de movimentação do mouse, por sua frequência elevada. Medições mostram que este evento tipicamente ocorre a uma frequência máxima de 50 eventos por segundo, o que significa que o tratamento de cada evento de mouse move deve ser efetuado em, no máximo, 1/50 = 20ms. Em TkVIX, o tratador de eventos de movimentação do mouse realiza, a cada execução, uma atualização do widget que se encontra sob o cursor do mouse. Esta tarefa tipicamente significa o percorrimento de parte da árvore de elementos, segundo a seguinte heurística: a partir da raiz da árvore, cada filho é consultado quanto à sua bounding box. Aquele cuja bounding box abrange

34

Page 48: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

as coordenadas do cursor repete o processo entre seus filhos, até que seja encontrado neste pmcesso um elemento que não possua filhos; este será então o elemento considerado como corrente. Este processo envolve a execução de alguns métodos e alguns níveis de recursão, a depender do quão aninhado se encontra o objeto. Vemos, portanto, que se, além desta tarefa, couberem muitas outras tarefas (ou mesmo poucas tarefas, mas de complexidade elevada) ao tratador de eventos de movimentação do mouse, o impacto disto pode ser a extrapolação da fatia de tempo reservada ao tratamento do evento, gerando atrasos perceptíveis pelo usuário.

A questão do desempenho do sistema ganha especial relevância com a utilização de Lua. Por ser uma linguagem interpretada, já se espera uma diferença de desempenho com relação a linguagens compiladas, como C++. Porém, há um aspecto ainda mais relevante: a chamada de uma função Lua que recebe parâmetros, a partir de C++, envolve uma chamada de função para cada parâmetro passado para Lua, além da chamada da função em si; isto é necessário para que os parâmetros sejam colocados na pilha de Lua, para poderem então ser coletados pela função. Situação semelhante ocorre no recolhimento dos parâmetros retornados por uma função Lua, que são colocados pelo interpretador na pilha, devendo de lá ser retirados. Com isto, é fácil ver que é interessante minimizarmos ao máximo a interação entre C++ e Lua.

Tendo isto em mente, procuramos garantir que os eventos recebidos do sistema gráfico nativo, tenham sido eles gerados pelo usuário final ou não, trafeguem o máximo possível pela árvore de objetos em C++, migrando para Lua apenas quando estritamente ne­cessário. Assim, salvo em situações especiais (exemplificadas mais adiante), os eventos percorrem toda a árvore de objetos C++ até chegar nas folhas, quando então são repas­sados aos objetos correspondentes em Lua.

Se imaginarmos a árvore que representa a hierarquia dinâmica determinada pelas re­lações entre os objetos de uma determinada interface, fazer com que os eventos trafeguem o máximo possível em C++ significa, em uma primeira análise, que os eventos só mi­grariam para Lua ao chegar nas folhas desta árvore, isto é, nos widgets que não são de composição ou, em outras palavras, aqueles que não podem possuir filhos. Mesmo possuindo cada nó intermediário (grupo) definido em C++ um correspondente em Lua, processamentos relativos a funcionalidades tais como filtragem de eventos não precisam ser repassados para Lua, podendo ser efetuados totalmente em C++. Porém, existem situações (as "situações especiais" a que nos referimos no parágrafo anterior) em que é necessário que grupos em Lua sejam notificados da ocorrência de determinados eventos. Alguns exemplos relevantes envolvem os eventos de repaint e resize.

Tratamento do evento de repaint

Em TkVIX, a única maneira de fazermos com que um objeto seja desenhado é através do evento de repaint. Uma característica importante deste evento é o fato de ele estar limitado a uma área retangular. A árvore de objetos é percorrida, a partir da raiz, e os ramos que não possuem interseção com esta área são descartados. Com isto, na maioria dos casos, apenas um subconjunto dos objetos que constituem a interface são desenhados. Além deste percorrimento seletivo da árvore, uma região de clipping idêntica ao retângulo de repaint é ativada, o que fará com que a camada gráfica ( Canvas Draw) descarte as primitivas que widgets eventualmente tentem desenhar fora da área de repaint;

35

Page 49: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

estas otimizações têm importante papel na redução do esforço envolvido no redesenho da interface.

Outros toolkits adotam mecanismos semelhantes: Fresco, por exemplo, implementa as chamadas damage regions, construídas através da operação need..redraw a partir de informações de widgets que tenham que alterar sua aparência 1 (por exemplo, um botão que é pressionado); caso o widget em questão esteja sob o efeito de transformações gráficas, a damage region a ser considerada corresponderá a uma área já transformada. As damage

regions são acumuladas, gerando a chamada "lista de reparos" (repa.ir list). O evento de repaint normalmente é gerado pelo sistema gráfico nativo, em resposta

a algumas situações específicas, a mais comum sendo o caso em que uma janela (ou parte dela) é desobscurecida. Porém, existe uma maneira de um objeto informar ao VS em que ele se encontra que uma determinada região deve ser redesenhada: trata-se do método Redraw, que recebe como parâmetro a área retangular a ser redesenhada. Sua funcionalidade é semelhante ao need..redraw de Fresco, com uma diferença relevante, porém: sendo um sistema multi-threaded, Fresco designa uma tarefa ( thread) específica para processar os pedidos acumulados na repa.ir list. Em TkVIX, o método Redraw é executado imediatamente pelo VS, o que, na prática, consiste da execução da callback de repaint do VO associado ao VS sobre a mesma área especificada ao método de Redraw, de maneira idêntica ao que aconteceria se o evento tivesse sido gerado pelo próprio sistema gráfico.

Uma característica relevante deste mecanismo de Redraw é o comportamento dos gru­pos; conforme foi visto na Seção 2.2, grupos são tratados ora como VS, ora como VO, dependendo do sentido em que se trafegue na árvore de elementos. Embora seu papel como VS possa sugerir que pedidos de Red:raw sejam por eles tratados, tais pedidos são sempre repassados para cima na árvore. Isto tem como finalidade permitir que todos os objetos que possuam interseção com a área de repaint sejam redesenhados, uma vez que grupos, por serem também VOs, podem possuir irmãos (outros VOs filhos do mesmo VS) que estejam a ele superpostos. Sendo assim, pedidos de Redraw percorrem a árvore no sentido da sua raiz, sendo tipicamente tratados pelo único VS que certamente não possui irmãos: o próprio diálogo. 2 Este comportamento com relação à requisição por um Redraw pode parecer, em uma primeira análise, desnecessário, se pensarmos em grupos apenas como hboxes e vboxes, pois estes elementos de composição não permitem superposição dos seus filhos. Porém, é importante lembrar que não devemos assumir este comporta­mento como único: o canvas, por exemplo, é também um grupo, que no entanto não impõe política de la.yout sobre seus filhos.

Por tudo que foi dito até o momento a respeito do evento de repaint, uma primeira análise pode nos levar a pensar que os grupos não precisariam recebê-lo, o que é verdade para elementos do tipo hboxes e vboxes, que não possuem decoração própria, apenas definem a política de posicionamento dos elementos sob eles agrupados. Porém, alguns elementos que atuam como grupos, como menus horizontais e o canvas, possuem decoração própria, devendo responder ao evento de repaint antes que seus filhos o façam; tipicamente,

1 Wídgets que precisem alterar suas dimensões não estão diretamente associados às damage regions, sendo tratados de maneira especial por Fresco, como veremos mais adiante.

2Nada impede, porém, que possa vir a existir uma especialização de grupo que redefina o comporta­mento de Redraw, de maneira que este seja tratado localmente.

36

Page 50: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

a área determinada pela bounding box do grupo deve ser pintada de uma certa cor antes que os filhos sejam redesenhados. Nestes casos, o grupo Lua também recebe o evento de repaint.

Para implementar este comportamento, as diferentes classes em Lua derivadas de gru­pos informam ao construtor do grupo C++ quais callbacks, entre as de repaint e resize o objeto Lua em questão está interessado em processar. Baseado nesta informação, o grupo C++ tem condições de decidir se deve ou não executar a callback Lua correspondente.

Dentre os widgets derivados de grupos, o canvas é o caso mais particular: além de tratar a callback de repaint, o objeto C++ redefine o método RedrawAll. Este método existe para complementar a funcionalidade do método Redraw: ele não trabalha com uma região, sendo portanto utilizado nas situações em que todo o diálogo deve ser redesenhado. Normalmente, um pedido por um RedrawAll é traduzido pelo VS associado ao diálogo em uma execução da callback de repaint sobre toda a área do diálogo. No caso do canvas, um pedido de RedrawAll recebido de um dos seus filhos é traduzido para um Redraw envolvendo a área do canvas como um todo; este pedido é então enviado para o VS que contém o canvas em questão (ver Figura 3.11).

bounding box (xmin, xmax, ymin, ymax)

···········•

vs

c11nvas

vo

aec!raw(xm.in, xmax, yain, :ymax)

aedrawAll ( )

Figura 3.11: Processamento do evento de RedrawAll pelo canvas

Tratamento do evento de resize

Com relação ao evento de resize, cabe a ele o importante papel de ser o responsável por desencadear o processo de reposicionamento dos widgets pelo diálogo, seguindo a política especificada pelo usuário na descrição da interface. A exemplo do evento de repaint, o resize usualmente é gerado pelo sistema quando as dimensões do diálogo são alteradas, mas existe um método (Resize) que é executado pelos widgets que tiveram sua dimensão alterada, como, por exemplo, um botão que teve seu label alterado, ou um hbox que agregou um novo filho. O procedimento é: cada widget para o qual a execução do método de Resize implicará no recálculo de suas próprias dimensões propaga o método para cima, no sentido da raiz da árvore, de modo que seu pai possa se adaptar a esta mudança de tamanho, se necessário; o processo termina no primeiro widget encontrado neste percorrimento que não seja afetado pelo redimensionamento dos seus filhos, ou na raiz da árvore. Novamente, este mecanismo é semelhante ao existente em Fresco: existe uma operação need_resize, análoga em funcionalidade ao método Resize de TkVIX.

37

Page 51: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

3.3 O algoritmo para hzyout abstrato

O posicionamento dos widgets nos diálogos merece especial atenção em toolkits para construção de GUis: os mecanismos de layout abstrato estão diretamente associados às políticas empregadas para distribuição de espaço entre os widgets. Não existe consenso ou norma a respeito de quais políticas devem estar implementadas, e nem de como deve ser a implementação das mesmas, embora algumas básicas, como as associadas a hboxes e vboxes, estejam presentes na maioria dos toolkits; existem, no entanto, pontos em comum: de uma maneira geral, a posição e o tamanho dos widgets são determinados pelo seu pai, baseado em informações fornecidas por eles próprios, tais como tamanhos mínimos e máximos. O widget de composição, baseado no seu próprio tamanho (que, por sua vez lhe foi fornecido pelo seu pai), decide qual o espaço a ser ocupado por cada um dos seus filhos. Este processo se repete recursivamente, a partir da raiz, até que a árvore tenha sido percorrida na sua totalidade.

No Intrinsics, a reorganização de widgets depende de uma intensa e complexa nego­ciação entre os mesmos: os widgets de composição possuem os chamados gerenciadores de geometria (geometry managers), que processam os pedidos para que as posições e/ ou dimensões de seus filhos sejam recalculadas. Estes pedidos podem ser atendidos, negados ou até mesmo negociados - o widget de composição pode concordar com uma configu­ração aproximada ao pedido dos seus filhos. Por exemplo, pode ser negado a um filho um pedido para que ele aumente para um determinado tamanho, mas pode ser permitido um aumento para um tamanho intermediário.

Em Fresco, os widgets de composição pedem aos seus filhos para que estes informem, para cada dimensão, os tamanhos pretendidos: mínimo, máximo e natural. Baseado nestas informações, o widget de composi!Ção distribui o espaço a ele associado, de acordo com a política condizente com sua semântica.

O algoritmo implementado em TkVIX leva em consideração, para cada objeto para o qual vai distribuir espaço, características tais como tamanhos mínimo e máximo e prio­ridades. Uma assertiva básica observada é: nenhum elemento recebe menos espaço do que o seu mínimo (todo elemento inicia a distribuição com tamanho nulo). Caso o tama­nho do diálogo seja insuficiente para comportar todos os elementos com seus respectivos tamanhos mínimos, o comportamento default do toolkit é exibir o que for possível dos elementos, como ilustra a Figura 3.12. Este comportamento, porém, pode ser alterado mediante a utilização do atributo forceain disponível para diálogos: caso este possua um valor não-nulo (diferente de nil), o toolkit definirá para o diálogo um tamanho mínimo, equivalente ao mínimo necessário em ambas as direções para comportar os elementos com seus respectivos tamanhos mínimos. O atributo forcemin pode ser utilizado em conjunto com os atributos minx e miny; neste caso, prevalece para cada direção o maior valor entre o mínimo necessário à exibição dos elementos e o especificado pelo usuário.

Uma vez distribuídos os tamanhos mínimos, cada elemento recebe mais espaço, em uma ou outra direção (ou mesmo em ambas, como é o caso do canvas), de acordo com sua capacidade de ainda absorver espaço e a sua prioridade.

O algoritmo para Jayout abstrato de TkVIX foi implementado inteiramente em Lua.

38

Page 52: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Figura 3.12: Diálogo colll tamanho insuficiente. para comportar os wídgets1

estando o atributo f orcemin associado ao valor nil

3.3.1 Prioridades

O mecanismo de prioridades de TkV!X funciona da seguinte maneira: cada elemento possui uma prioridade default associada a si .. Cabe a cada widget de composição manter controle sobre a maior prioridade dentre os seus filhos; uma vez identiliçado, este valor passa a ser a prioridade do próprio widget de composição, e apénas os widgets que possuírem prioridade igual a esta serão considerados na divisão do espaço disponível. A necessidade por um. mecanismo de prioridades surgiu, a princípio, da possibilidade de se combinar fi.lls e canvas, em uma mesma interface. Se o algoritmo não considerasse prioridades, fi.lls e canvas teriam o mesmo peso na distribuição de espaço, o que, na prática, resultaria no fi.11 competindo em igualdade de condições por espaço que deveria ser destinado ao canvas pois, tipicamente, canvas são utilizados para visualização de primitivas gráficas, ao passo que fills são utilizados apenas para dispor corretamente os elementos na interface. Um exernplo em que um bbox possui como filhos um fill, um canvas e outro fill, nesta ordem, tendo os íills um tamanho mínimo, é ilustrado na Figura 3.13; na Figura 3.13(b), os fills possuem seu tamanho mínimo, e o c.a.nvas recebeu todo o espaço restante, o que caracteriza a situação correta.

(a) Sem prioridades (b) Com prioridades

Figura 3.13: Impacto da utilização de prioridades

IUP possuí um mecanismo de prioridades semelhante, no que diz respeito ao fi.11 e ao canvas. A diferença é que em IUP este mecanismo é interno e inacessível ao usuário, e tem como finalidade específica resolver sta questão da competição por espaço entre fills e ca.nvas. Em TkVIX, estendemos a funcionalidade do mecanismo de prioridades, associando-as a atributos dos objetos, possibilitando portanto sua utilização por parte do

39

Page 53: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

usuano. Além disto, ampliamos a gama de possíveis prioridades, disponibilizando até 5 níveis de prioridade, estando este limite associado a uma constante definida em Lua -podendo, portanto, ser facilmente alterado. A prioridade default dos widgets (incluindo fills) é O (zero), ao passo que a do canvas é 1 (um).

O processo de distribuição de espaço é iniciado de duas maneiras: através do recebi­mento de uma callback de resize ou em resposta à execução do método Resize. No caso da ca.llba.ck, o primeiro elemento da árvore recebe do diálogo suas novas dimensões; no caso do método, um dos VSs na cadeia de execuções não terá que alterar seu tamanho, não precisando, portanto, propagar o pedido de Resize. Começa então um processo re­cursivo onde o espaço vai sendo dividido entre os filhos, até que não haja mais espaço a ser distribuído ou não haja na subárvore em questão mais elementos capazes de absorvê-lo.

Elementos que não são widgets de composição limitam-se a absorver espaço, aqueles que o são têm como responsabilidade, sabendo quantos e quais filhos podem absorver es­paço em cada direção, distribuir o espaço recebido, observando sempre a assertiva básica de que os widgets não recebem menos espaço do que o seu tamanho mínimo e as prio­ridades existentes entre os elementos, garantindo que os tamanhos mínimos e máximos sejam respeitados. O espaço não aproveitado, em ambas as direções, por cada widget, é devolvido ao seu pai, para que este possa tentar redistribuí-lo entre seus outros filhos.

Por sua natureza, hboxes e vboxes possuem comportamentos distintos, ainda que análogos, quanto à distribuição de espaço:

Hbox o espaço vertical é distribuído em uma única passagem; não cabe ao hbox tomar nenhuma decisão a respeito da absorção de espaço vertical pelos seus filhos. O espaço horizontal, por sua vez, é iterativamente distribuído entre os filhos. A cada iteração, é calculada uma fração a ser distribuída pelos filhos ainda expansíveis na direção horizontal, levando-se em consideração o espaço ainda disponível, quantos ainda se encontram nesta situação e as diferentes prioridades dos mesmos. Esta fração é então oferecida a cada filho, que, caso venha a atingir seu tamanho máximo com esta incorporação de espaço, retorna o espaço que eventualmente tenha sobrado, informando ao seu pai que não deve mais receber espaço na direção horizontal. O processo se repete até que não haja mais espaço horizontal a ser distribuído ou filhos aptos a absorvê-lo.

Vbox o processo é análogo, possuindo como diferença apenas o fato do vbox privilegiar a direção vertical ao invés da horizontal.

Após distribuir espaço para um filho, durante uma iteração, um widget de composição atualiza as informações nas quais se baseia para determinar as frações a serem distribuídas. Por exemplo, se o filho de um hbox atingiu seu limite máximo na direção horizontal, o hbox saberá, na próxima iteração, que não precisará considerar este mesmo filho no cálculo da fração de espaço horizontal destinado a cada filho. Além disto, para cada widget desconsiderado em uma determinada iteração, caso sua prioridade seja maior do que a default (zero), um contador no widget pai é decrementado. O motivo disto é gerenciar adequadamente a prioridade corrente do wídget de composição - aquela que determinará quais dos widgets participarão da distribuição de espaço. Caso o widget desconsiderado tenha sido o último com uma determinada prioridade maior do que a default, a prioridade do widget de composição é recalculada.

40

Page 54: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Uma vez realizada a distribuição do espaço, todo widget já tem conhecimento do tamanho que ocupará no diálogo, mas não está ainda ciente da sua posição. É feito então mais um percorrimento da árvore de elementos, com cada widget de composição atualizando as posições dos seus filhos.

3.3.2 Exemplos

Apresentaremos agora alguns exemplos de especificação de interfaces, ilustrando como o algoritmo para Jayout abstrato lida com diferentes situações. Aproveitaremos a ocasião para apresentar algumas funcionalidades do toolkit. Alguns dos exemplos farão uso de widgets nativos Motif, cuja incorporação ao toolkit será detalhada na Seção 3.5.

Exemplo 3.1: Prioridades

A fim de ilustrar o tratamento de prioridades por parte do toolkit, apresentamos agora um exemplo que consiste apenas de um diálogo com um canvas e alguns fi.lls. A descrição deste diálogo segue abaixo.

d1 = Dialog {width=120, height=100, title= 11Priorities 11}

h1 = Hbox {d1} Fill {h1; min=10} v1 = Vbox {h1}

Fill {v1; min=10} Canvas {v1; min="100x30", max="150x100"} Fill {v1; min=10}

Fill {h1; min=10}

Conforme visto na Seção 3.3.1, o canvas é um elemento expansível por default, com prioridade maior do que os demais elementos. Estando o diálogo com seu tamanho inicial, o canvas não atingiu ainda suas dimensões máximas, recebendo portanto todo o espaço disponível a menos dos mínimos exigidos pelos tills, conforme podemos constatar através da Figura 3.14(a). A Figura 3.14(b) ilustra a situação em que o diálogo foi aumentado, de modo que o canvas pôde alcançar seu limite na direção horizontal; nesta situação, por não poder absorver mais espaço, o canvas habilita o algoritmo a redistribuir o espaço não aproveitado por ele entre elementos de prioridades mais baixas (neste caso, os fills).

A Figura 3.15 ilustra a mesma situação da Figura 3.14(b), a menos do fato de que agora os fi.lls possuem prioridade igual à do canvas (o que foi conseguido através da associação do valor 1 ao seu atributo priority). O resultado disto pode ser constatado através das dimensões do canvas: sua altura é igual à de cada um dos fi.lls verticais, e sua largura é igual à de cada um dos fi.lls horizontais, significando que o espaço disponível foi dividido igualmente entre os elementos.

Exemplo 3.2: Diálogo para confirmação

Nosso próximo exemplo consiste de um diálogo para confirmação, possuindo uma mensagem indicativa do seu propósito e botões para confirmar a operação em questão ou cancelá-la.

41

Page 55: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

'·-1 ~ 1

Pl'iorities 1 · : r- J

;1 ti

(a) (b)

Figura 3.14: Distribuição de espaço entre fills e canvas

confirm_dlg = Dialog {width=230 ,_ height=115, title="Confirmation request"}

v1 = Vbox {conf irm_dlg} Fill {vi}

hO = Hbox {vl} Fill {hO} Label {hO; text="Please confírm operation11

}

Fill {hO}

Fill {vl} hl = Hbox {v1}

Fill {h1} Button {h1; label=11 Confirm 11

, button_cb="confirm_cb(1) 11}

Fill {h1; min=20 , max=200} Button {h1; label= 11 Cancel 11

, button_cb= 11 confirm_cb () "} Fill {hl}

Fill {v1}

Neste exemplo, associamos às caJJbacks de ambos os botões a função confirm_cb, que receberá como argumento um indicador da escolha. do usuário.

Cabe aqui uma observação a respeito de callbacks de botões: conforme dito anterior­mente, o atributo button_cb pode ser associado diretamente à função a ser executada quando o botão for pressionado, ou a uma string, cujo conteúdo será executado pelo tool­kit nesta mesma situação. A opção por se associar diretamente uma função ao atributo button_cb possui duas restrições relevantes. A primeira é que a função deve obrigato­riamente já ter sido definida, pois, em caso contrário, button_cb será associado ao valor nil, e não a um valor do tipo function ou CFunction; isto acontece porque os atributos

Figura 3.15: Fills com mesma p ·ioridade que o canvas

Page 56: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

í· -·r . Conrlm1atiÕn::. request;--·i:-rr

Figura 3.16: Diálogo para confirmação

do botão são associados a seus valores apenas na i11stanciação deste. A segunda restrição é a de não ser possível passar argumentos à callback desta maneira. Uma atribuição do tipo

Button { ... , button_cb = callback_function(args), .. . }

faria com que Lua executasse a função callback_function, fornecendo a esta os argu­mentos especificados, no momento da instanciação do botão, e não quando este fosse pressionado. A associação de callbacks a strings consiste de um recurso para se contor­nar esta limitação, uma vez que a string será executada apenas no momento em que o botã.o for pressionado. Corno característica adicional, strings permitem que mais de um comando seja especificado, desde que separados por ponto-e-vírgula.

Um modelo para a callback confirm_cb é apresentado a seguir. A sequência de ca­racteres "--" significa, em Lua, o início de um comentário.

function conf irm_cb (conf irmed) if conf irmed then

process the confirmation ... els e

process the cancelation ... end confirm_dlg:Hide()

end

Observar a especificação de tamanhos mínimo e máximo para o fill entre os botões, fazendo com que o espaço entre estes nunca chegue a menos do que vinte pixeis ou mais do que duzentos.

Exemplo 3.3: Floating toolbar

Para se obter uma janela contendo apenn.s botões (floating toolbar), dispostos vertical­mente como nos mostra a Figura 3.17, descreveríamos a interface de maneira.semelhante ao apresentado abaixo.

tbar = Dialog {title= 11 11 width=80, height=350, forcemin=1} vl = Vbox {tbar}

Button {v1; label= 11 0pen11, expand=HORIZONTAL}

43

Page 57: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Figura 3.J 7: Toolbar

Button {vl; label= 11Save11, expand=HORIZONTAL}

Button {vl; label="Save As", expand=HORIZONTAL} Fill {vl; size=lO} Button {vl; label=11Cut 11

, expand=HORIZONTAL} Button {v1; label: 11 Copy 11

, expand=HORIZONTAL} Button {v1; label="Paste" , expand=HORTZONTAL} Fill {vl; size=10} t _but = Button {v1; label="Tools ... 11

, expand=HORIZONTAL, button_cb=toggle_tools_dlg}

Fill {vl; s ize=10} Button {v1; label=11Help 11

, expand==HORIZONTAL} Button {v1; label="About", expand=HORIZONTAL} Fi l l {vl; mi n=10} Button {v1; label="Exit", fgcolor=CD_ RED, button_cb=exit,

expand=HORIZONTAL}

Características:

• uso do atributo forcemin do diálogo, de modo a garantir que suas dimensões mínimas correspondam à soma das dimensões mínimas dos elementos nele conti­dos;

• uso do atributo expand1 indicando que os botões podem ser expandidos na direção horizontal. Neste nosso exemplo, isto tem como finalidade garantir que todos terão o mesmo tamanho horizontal, independente do texto a eles associados;

• a utilização de fills com tamanho fixo, com a finalidade de inserir espaços fixos entre grupos de botões.

44

Page 58: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Tipicamente, cada botão teria associado a si uma callback. Neste ,exemplo, o fizemos apenas com um dos botões> que terá como função eltlbir um segund0 dialogo. Este botão; associado ao identificador t_but, possui como callback à função toggle_toóls_dlg, apre­sentada a seguir.

function toggle_tools_dlg O if no't tools_dlg: lsVisíble() then

tools_dlg:Show() t_but.fgcolor = CD_BLUE

els e tools_dlg ;;Hide () t_but.fgcolor = CD_BLACK

end t_but :RedravO

end

Esta função exibe o segundo diálogoi caso este já nâ9 esteja visível, ou esconde..o, em caso contrário~ Para tal, ela. consulta o próprio diálogo quanto. ao se.u estado atual, através do método IsVisible. 3 Como funcionalidade adicional, ela altera a cor do te::do do botão t_but, de modo a indicar se o diálogo .s~ encontra visível ou não. Observar a execução do método Redraw do botão para que est_e atualize sua aparência,

Finalmente, o diálogo e:xibído quandq o botão t_but é pressionado possui a Seguinte, descrição:

tools·_dlg = Dialog {title= 11Too1su, forcemin=1} v2 = Vbox {tools_dlg}

h2 = Hbox {v2} Button {h21; label="Spell\nChecker11

, expand:::CBOTH} Button {h21; label=i1Auto\nformat 11

• expand=BOTH} Button {h21; labe1= 11 0ptions ... ... , expand=BDTI{}

Figura 3.18: Diálogo secundário

Características:

• não é especificado um tamanho para este diálogo; normalmente, isto levaria à utili­zação de valores defa.ult. Porém, devido à utilização do atributo forcemin, garante­se que o diálogo terá como tamanho inicial o menor tamanho necessário à exibição · dos botões nele contidos;

3 A execução de um método sob a forma objeto: método ( ... ) é traduzido internamente pelo interpre­tador Lua para objeto. método (self, ... ) , onde elf é o objeto sobre o qual o método será executado, que pode então manipulá-Jo. Este objeto desempenhat portanto, um papel análogo ao ponteiro this pas­sado aos métodos por e++.

45

Page 59: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

• uso da sequência de caracteres "\n" para forçar quebras de linha nos textos dos labels dos botõesj

• uso do atributo expand para garantir que todos os botões tenham a mesma altura, independente do fato de terem ou não Jabels distribuídos em múltiplas linhas.

Exemplo 3.4: Calculadora

A Figura 3.10 foi utilizada na Seção 3.2.1, com a finalidade de ilustrar o impacto dos parâmetros de expansibilidade nos widgets. Apresentaremos agora a descrição em Lua utilizada para se conseguir o diálogo apresentado, com suas características particulares.

d= Dialog {width=140, height=240, title= 11 Calculator 11, forcemin=1}

vl = Vbox {d} Label {vl; text= 11 0.00 11

, fgcolor=CD_BLUE, alignment=RIGHT, expand=BOTH}

hO = Hbox {v1} Button {hO; label= 11 +11

, expand=BOTH, f gcolor=CD_RED} Button {hO; label='1

-11

, expand=BOTH, f gcolor=CD_RED} Button {hO; label= 11 *", expand=BOTH, f gcolor=CD_RED} Button {hO; label= 11

/11

, expand=B01H, fgcolor=CD_RED} Fill {vi; size=10} h1 = Hbox {vi}

Button {h1; label= 11 711, expand=BOTH}

Button {h1; label= 11 811, expand=BOTH}

Button {h1; label= 11 911, expand=BOTH}

h2 = Hbox {vi}

Button {h2; label="4", expand=BOTH} Button {b2; label= 11 511

, expand=BOTH} Button {h2; label= 11 611

, expand=BOTH} h3 = Hbox {vi}

Button {h3; label= 11 111, expand=BDTH}

Button {h3; label= 11 211, expand=BOTH}

Button {h3; label="3 11, expand=BDTH}

h4 = Hbox {v1} Button {h4; label= 11 011

, expand=BOTH} Button {h4; label= 11

• 11

, expand=BOTH} Button {h4; label= 11 =11

, expand=BOTH, f1~color=CD_BLUE}

Com relação aos demais exemplos, este possui como diferencial a utilização do atributo alignment para o label associado ao visor da calculadora, de modo que o texto seja exibido justificado à direita. Isto por si só, porém, não nos garante o efeito desejado; faz­se necessário também a utilização do atributo de expansibilidade expand, de modo que a largura do la bel seja sempre igual à largura do diálogo (neste exemplo, o label não disputa espaço horizontal com nenhum outro widget.). Observar, através da Figura 3.lO(b), como

46

Page 60: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Figura 3.19: Calculadora

a configuração do label como expansível verticalmente poupa a utilização de fills para ceutralizá-lo nesta direção.

Exemplo 3.5: Entrada de dados

Este exemplo consiste de um diálogo para uma entrada de dados simples, contendo ape­nas duas caixas-de-texto e botões para confirmaçiio e cancelamento. Ainda que simples, este exemplo possui o mérito de ilustrar a integração de widgets nativos e não-nativos. A descrição em Lua da interface é apresentada a seguir.

dlg = Dialog {width=250, height=180, title= 11 User Information11

f orcernin=l} vi = Vbox {dlg}

Fill {vl}

h1 = Hbox {v1; alignment=CENTER} Fill {h1} Label {h1; text="Name : 11

}

tf_name = XmTextField {h1; columns=20} Fill {h1}

Fill {v1}

h2 = Hbox {v1; alignment=CENTER} Fill {h2}

Label {h2; text=11 Address: 11}

tf_address = XmTextField {h2; Fill {h2}

Fill {v1}

h3 = Hbox {v1} Fill {h3}

Button {h3; label=11

Fill {h3} Ok li

Button {h3; label=" Cancel 11

Fill {h3}

columns=20}

button_cb=exit_ok}

button_cb::::exit}

47

Page 61: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Fill {v1}

A Figura 3.20 ilustra o resultado obtido a partir da descrição acima. Os widgets Motif sã.o exibidos e tratados, no que diz respeito a política de Jayout, como os demais widgets não-nativos; se a janela é redimensionada, as caixas-de-texto Motif são reposicionadas1

mantendo suas posições relativas aos demais widgets. Como característica deste exemplo, cabe chamar atenção para a utilização do atributo

alignment dos hboxes hl e h2 para fazer com que o la.bel e a caixa-de-texto fiquem alinhados verticalmente. Além disto, associou-se à callback do botão de confirmação a função exi t_ok, que tem como função exibir no terminal os conteúdos das caixas-de­t~xto. Para tal, utilizou-se o método GetData das caixas-de-texto. O código desta função é apresentado abaixo.

function exit_ok () print ("name = 11

•• tf _name: GetDataO) print("address = " .. tf_address:GetDataO) exitO

end

Figura 3.20: Diálogo para entrada de dados contendo widgets nativos e não-nativos

Ê importante ressaltar que os widgets Motif mantêm suas funcionalidades; por exem­plo, os mecanismos de seleção e cópia de texto através do mouse, normalmente associados a caixas-de-texto Motif1 estão plenamente funciona.is para as caixas-de-texto do exemplo.

Exemplo 3.6: Listas

Neste exemplo, apresentaremos a descrição da interface apresentada na Figura 3.21, em conjunto com uma discussão a respeito de suas características.

dlg = Dialog {width=300, height=200, title="List boxes", forcemin=1} hO = Hbox {dlg} Fill {hO; size=20}

vO = Vbox {hO} Fill {vO; min=20} h1 = Hbox {vO}

48

Page 62: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

I' - ' .:::1 - _......,, - •

,- wtlloxes I • i

first $ecoM th!rd

l tea teat· 1

Figµra 3.21: Diálogo do exemplo 3.6

tl1 = XmList {h!; rolls=5, vrovs=3. cols=20; multiple=1, items.={ 11first 11

• 11 secónd11

• 11 third"}}

Fill {h1 ;. min=10} tl2 = XmList-{h1; rows=5, vrows=3._ cols=10,

items={" 1.st". 11 2nd". 113rd'11 .. "'4th". "5th"}}

Fill {vO; min=10} h2 = Hbox {vO: alignment=CEN'TER}

Labe_l {h2; text= 11 Item téxt: 11., expand=HORIZO.NTAt,

alignment=RIGHT} tb = XmTextField {h2; cols=20}

Fill {vO; min=~O} h3 = Hbox {vO}

Fill {h3} Button {h3; label=" .Change 11 butto;n_cb=.ch,angeitem} Fill {h3; min=50} Button {h3; label=" :End 11 button_cb=exit} Fill {h3}

Fill {vO; min=20} Fill {hO; size=20}

Como características deste exemplo, podemos citar:.

• tratamento indiscriminado de' widgets nativos e n~nativos por parte do algoritmo· de iayout abstrato. Colil rel~ção às lis~as (elementos XmLi st), çabe aqui uma breve EPCplicação a respeito de alguns dos at_f.ibutos ·ut.Uiz.ª"-10.s:

- .o atributo rovs ,indiêá qtianta.c;i lin.has a; lista ter~, nQ tota}_; ,o atributo vrows .é opcional e indica quantas destas linhas'sétão vfaíveis. Caso ·vrows seja. menor do .que. rows, uma scrollbar vertical .é eriada automaticamente~

- o atributo cols indicá. ô número de col:uu~ que a I.~t<J. posstiirá. Caso álgum de seus elementos possua um tamanho maior do qúe. o número de colunas da lista, uma, scrollbar horizontal é autom~ticament~ criadai

49

Page 63: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

- o atributo multiple indica que a lista em questão permitirá a seleção de mais de um elemento simultaneamente.

· • utilização de um hbox e um vbox externos (hO e vO), de modo a garantir uma borda de 20 pixels em torno de todo o diálogo. Os /i.lls de tamanho fixo empregados como borda lateral do diálogo, em conjunto com outros /i.lls horizontais fazem, com que os elementos situem-se sempre a uma distância fixa das margens laterais, de maneira semelhante ao que é conseguido, por exemplo, no Motif com o widget de composição XmForm. A diferença é que, no caso do Motif, os widgets inseridos em um XmForm é que devem indicar sua intenção de se posicionar a uma distância fixa de uma ou mais margens.

• Configuração do label como expansível horizontalmente e alinhado à direita, empur­rando a caixa de texto para a direita e colocando-se junto a este, poupando portanto a utilização de um fi.11 horizontal.

• Uso do atributo alignment do hbox h2, de modo a garantir que o label e a caixa de texto fiquem centralizados verticalmente.

A fim de testarmos a manipulação de widgets nativos, associamos à callback de um dos botões uma função com o seguinte propósito: dado que existe um elemento selecionado na segunda lista, substitui o item da primeira lista que ocupa a mesma posição relativa pelo conteúdo da caixa de texto. A função, denominada changeltem, consiste simplesmente do seginte trecho de código:

function changeltem () sel = tl2:GetSelltems() if not sel then return end local i,v = next(sel, nil) tl1:Changeltem(i, tb:GetData())

end

O método GetSelltems retorna, para uma determinada lista, uma tabela onde cada elemento selecionado da lista está associado ao índice correspondente à sua posição na lista; assim, no exemplo acima, se a lista tl2 possui os ítens 2 e 5 selecionados, sel [2] é igual ao primeiro item e sel [5] é igual ao segundo. Caso nenhum item tenha sido selecionado, GetSelltems retorna nil. A função next, pré-definida por Lua, oferece uma maneira de se percorrer todos os campos de uma tabela sem que seja necessário saber-se de antemão quais são estes. Ela recebe como argumentos a tabela a ser pesquisada e o último campo acessado, retornando o próximo campo e o valor associado a este. O fornecimento de nil à função como último campo acessado indica que se está interessado no primeiro campo. O método Changeltem altera o item de uma tabela associado a uma determinada posição, e o método GetData retorna o texto associado a uma caixa de texto.

50

Page 64: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

3.4 Integração com C++

De acordo com o que já foi visto neste doc111mento, os objetos tratados pelo toolkit são tabelas Lua, representando objetos das classes associadas aos widgets; com isto, procurou­se permitir que o usuário do toolkit crie as interfaces de que precisa exclusivamente em Lua. Eventuais widgets não presentes dentre os pré-definidos pelo toolkit que se mos­trem necessários podem ser criados diretamente em Lua, através da herança de classes já implementadas.

Porém, de modo a conferir maior flexibilidade ao toolkit, implementou-se um mecanis­mo que possibilita a co-existência de objetos Lua e objetos C++ em uma mesma árvore de objetos. Através deste mecanismo, novos tipos de objetos podem ser criados direta­mente em C++ e ser inseridos como filhos de grupos Lua (hbox, vbox, canvas etc.), sendo tratados por estes da mesma forma que os demais objetos. Este recurso é fundamental pa.ra que filtros definidos em C++ possam atuar sobre widgets definidos em Lua, por exemplo. Outras situações em que este recurso se mostra útil são aquelas em que são necessários objetos extremamente eficientes, em termos de tempo de resposta, ou quando são necessários objetos que dependem de inúmeras rotinas C++ que não serão registradas em Lua.

A coexistência de objetos C++ e Lua em um mesmo espaço de dados é possível, fundamentalmente, graças à existência do tipo userdata - essencialmente, um ponteiro para um objeto C++. Antes de ser armazenado em Lua, um ponteiro C++ para um objeto deve ser convertido para um ponteiro para void; isto torna impossível, quando da posterior recuperação deste objeto por C++, a inferência do tipo original do objeto. Para auxiliar o programador na obtenção de informações a respeito de userdata armazenados em Lua, existe uma informação adicional que pode ser a eles associada: trata-se do tag, um número inteiro positivo cuja utilização será exemplificada mais adiante.

Porém, o tipo userdata, por si só, não é suficiente para permitir a homogeneização C++ +--+ Lua desejada; para tal, faz-se necessário utilizar o mecanismo de mensagens implementado no framework, conforme descrito a seguir.

3.4.1 O mecanismo de mensagens

Uma das tarefas mais executadas pelo toolkit consiste de acessos a tabelas Lua; a todo instante, os objetos têm seus atributos consultados e/ou alterados. Some-se a esta si­tuação, extremamente comum, as execuções de métodos Lua, uma vez que, antes de estes serem executados, as funções correspondentes devem ser recuperadas dentre os campos do objeto. Para Lua, um userdata é uma espécie de "caixa-preta", não há meios de se acessar campos ou métodos - tais tentativas levam a situações de erro. Sendo assim, é fácil ver que um widget de composição que possua entre seus filhos objetos do tipo userdata (provenientes de C++, portanto) não pode, na configuração usual do ambiente Lua, executar sobre estes objetos as mesmas operações executadas sobre os demais filhos. Esta limitação, se impossível de ser contornada, impossibilitaria a coexistência de objetos C++ e Lua.

Felizmente, Lua oferece, através do mesmo mecanismo de fallbacks empregado na implementação do modelo de orientação a objetos, meios para possibilitar a consulta, a partir de Lua: de campos de objetos C++. Explicaremos a seguir como isto é conseguido.

51

Page 65: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

A idéia é: dado que se deseja acessar um campo de um objeto userdata, deve-se requisitar à camada C++ da aplicação (resp0nsável pela definição do objeto em questão) que retorne o objeto Lua associado ao campo em questão. O objetivo é fazer com que a utilização de objetos userdata por funções Lua se dê de maneira transparente, sem que as funções tenham que levar em consideração se o objeto que estão manipulando é nativo de Lua ou proveniente de C++.

Do ponto de vista de Lua, o suporte que deve existir consiste da redefinição da fallback de gettable. Esta fallback é executada pelo interpretador Lua quando tenta-se acessar um campo de um objeto que não é uma tabela; ela recebe como argumentos o objeto e o campo acessados, e deve retornar como resultado um objeto Lua. A nova gettable testa o tipo do objeto recebido; caso não se trate de um userdata, a fallback default de Lua é executada. Em caso contrário, porém, uma mensagem é enviada para um tratador default C++ (VixThrowMsgField), previamente registrado em Lua. Neste estágio, o "envio da mensagem" consiste simplesmente da execução de uma função C++, que recebe como parâmetros, a exemplo de gettable, o objeto e o índice acessados.

Do ponto de vista de C++, a função, baseada no tag associado ao userdata, determina se se trata de um VS ou VO; isto é necessário para que possa ser efetuada a conversão do tipo void para o tipo correto. Tendo em mãos o objeto, já com seu tipo original restaurado, VixThrowMsgField o envia uma mensagem, para que este possa responder, se possível, com o objeto Lua a ser retornado. Já estamos fazendo uso, neste estágio, do mecanismo de suporte a troca de mensagens entre objetos implementado pelo framework.

Todas as mensagens gerenciadas pelo framework possuem um supertipo comum, mode­lado pela classe abstrata VixMessage; todas as mensagens que transitam pelo framework são, antes do envio, convertidas para este tipo. Existem métodos específicos para identi­ficação do tipo de uma mensagem recebida como VixMessage, assim como métodos para envio de mensagens para VOs e VSs; estes, por sua vez, possuem tratadores (handlers) para as mensagens que podem receber. Cabe aqui chamar a atenção para o caso particu­lar dos filtros; por sua natureza "híbrida" (VO+-+ VS), são tratados ora como VOs, ora como VSs, dependendo da maneira pela qual o objeto Lua foi acessado. Cabe ao progra­mador se certificar de que as mensagens provenientes de Lua sejam atendidas, sejam elas endereçadas ao filtro enquanto VS ou enquanto VO.

Para viabilizar a troca de mensagens com Lua, foram definidas em C++ duas sub­classes de VixLuaMessage: LuaGetFieldMsg e LuaObjMsg (a hierarquia é apresentada na Figura 3.22).

,------- ... ----, :ri.....,.: 1 1

Figura 3.22: Tipos de mensagens em C++

LuaGetFieldMsg é a mensagem utilizada quando Lua precisa recuperar um campo de um objeto que não é uma tabela, mas sim um userdata; ela possui os campos

52

Page 66: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

relacionados na tabela 3.2. O campo field é preenchido por VixThrowMsgField com o nome do campo requisitado por lua, e a mensagem é então enviada para o VO/VS do qual se deseja obter a i111formação. O campo luafield será então preenchido pelo tratador do elemento com o objeto Lua correspondente ao campo requisitado, caso isto seja possível. Em caso contrário, retorna-se para Lua o valor nulo {nil), fazendo com que a fallback em Lua execute a sua predecessora (a fallback original, que foi redefinida), o que provavelmente resultará em uma situação de erro.

campo tipo

luaf ield ll.ua_Object f ield char *

Tabela 3.2: Campos da mensagem LuaGetFieldMsg

LuaObjMsg é a mensagem utilizada quando, a partir de um VO ou um VS em C++, é preciso obter o objeto Lua a ele associado. Seu maior uso é feito por parte do próprio framework, quando um evento deve ser propagado para um objeto Lua. Esta mensagem possui o campo luaobj, do tipo lua_Object, a ser preenchido pelo tratador do VO/VS.

Com a combinação do mecanismo de faHbacks de Lua e do sistema de mensagens do framework, é possível implementar um esquema onde a "aceitação" de objetos C++ no espaço de dados de Lua é viável - dependendo, obviamente, da existência de tratadores de mensagens adequados no objeto C++, de modo que todas as requisições de Lua sejam atendidas.

3.4.2 Herança múltipla e conversão de tipos

Conforme vimos, objetos C++ são armazenados em Lua após conversão para o tipo (void *), e a correta identificação do seu tipo original é feita com o auxílio de um tag que pode ser associado ao objeto.

Este recurso é fundamental para a correta manipulação dos objetos C++ compartilha­dos com Lua. Porém, o fato de algumas das classes C++ estarem relacionadas através de herança múltipla acarreta problemas adicionais com relação à tipagem dos objetos. Tome­mos como exemplo a classe VixTypeFilter, que modela os filtros básicos de VIX; como podemos ver através da Figura 3.23, esta classe herda simultaneamente de VixTypeVO e VixTypeVS.

,-----------, .... --------- ... , : VlxTypeVO : : V/xTypeVS : 1 1 1 '

-----~-----

' r

: VlxTypeFI,,,,,. : 1 r

Figura 3.23: Hierarquia de classes do filtro básico de VIX

53

Page 67: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Filtros, como já sabemos, possuem natureza híbrida, e são tratados ora como VS, ora como VO, dependendo do sentido em que se trafegue na árvore de objetos. Isto acarreta o seguinte problema de ordem prática: suponhamos um filtro que seja armazenado em Lua como VO; se, ao ser recuperado em C++, ele desempenhar novamente o papel de VO, uma conversão direta para (VixTypeVO *) é correta e suficiente. Porém, se ele for necessário não como VO, mas sim como VS, a conversão direta para (VixTypeVS *) não é correta, invariavelmente confundindo o mecanismo de tipos de e++ - a tabela de métodos do objeto é encarada de maneira errônea, levando a um comportamento imprevisível do programa durante sua execução.

A forma correta de se evitar este tipo de comportamento é fornecer ao mecanismo de tipos de C++ as informações de que ele precisa para manipular corretamente a tabela de métodos dos objetos. Isto é conseguido, no nosso exemplo, fazendo-se uma conversão para o tipo VixTypeFilter antes da conversão para VixTypeVS.

De uma maneira geral, deve-se seguir a seguinte regra: a conversão de um tipo para outro de um ramo diferente da hierarquia de tipos, onde existe um supertipo comum aos dois, deve ser feita através da conversão par.a o supertipo comum (ver Figura 3.24).

B *b • new B( ••• )

e •e• (C *)((A *)b)

Figura 3.24: Conversão de tipos entre ramos diferentes da hierarquia

Com o objetivo de doutrinar a troca de dados entre Lua e C++, evitando os problemas associados à conversão de tipos entre classes, criou-se uma série de funções para armaze­namento /recuperação de dados C++ em Lua: LuaSetVS, LuaGetVS, LuaSetVO etc. Estas rotinas armazenam os dados fornecidos juntamente com um ta.g indicativo da natureza dos mesmos. Uma vez que, como já foi visto, os dados C++ são armazenados em Lua como userdata (ou seja, são convertidos para (void *)), o tag passa a ter fundamental importância: através dele é possível efetuar uma checagem quando da recuperação do da­do em Lua, evitando que um ponteiro para um determinado tipo de objeto seja recuperado errôneamente como um ponteiro para outro tipo de objeto, o que, se não evitado, levaria a resultados imprevisíveis durante a execução do programa. Nas situações em que estas funções detectam uma tentativa de conversão ilegal, uma mensagem de erro indicando o tipo de conversão tentada é exibida, e o programa é interrompido; é preferível isto a ter de lidar com erros decorrentes da utilização indevida de ponteiros. Deve-se, no entanto, estar atento para o fato de que nem toda conversão deve ser encarada como ilegal: um exemplo clássico é a recuperação de um filtro como VO, tendo ele sido armazenado como VS. Estes casos são devidamente tratados por estas funções, desempenhando mais uma vez o tag um papel fundamental.

É importante ressaltar que este cuidado na manipulação de objetos C++ cujo tipo é construído através de herança múltipla deve ser tomado independentemente de ser ne­cessária uma conversão intermediária para (void *),isto é, independentemente do objeto ser armazenado em Lua.

54

Page 68: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

3.5 Widgets nativos

A incorporação de um novo widget ao framework pode requerer um esforço não muito grande por parte do programador, de acordo com sua funcionalidade; um exemplo ilustra­tivo são os round buttons, cuja implementação essencialmente consiste da redefinição dos métodos da classe Button relativos à geometria do widget. Por outro lado, a incorporação de widgets tais como listas de elementos (Jist-boxes), ou mesmo uma "simples" caixa-de­texto ( text-box), pode envolver um esforço considerável, dado a complexidade inerente aos mesmos. Tomemos como exemplo a text-box; do ponto de vista do usuário final, trata-se de um elemento de interface dos mais simples: um "editor de textos" simplificado, de apenas uma linha. Porém, do ponto de vista do programador, há um grande número de aspectos técnicos que devem ser considerados, dos quais podemos citar o gerenciamento do cursor (posição corrente, limites, exibição), a exibição dos caracteres digitados, o correto e eficiente armazenamento destes em um bulfer (considerando, obviamente, as operações de inserção e remoção de caracteres), o tratamento dos eventos de teclado (algumas teclas não correspondem a caracteres a serem exibidos, mas sim a ações a serem efetuadas).

No Capítulo 2, analisamos alguns dos toolkits existentes para construção de interfaces gráficas. Embora não haja consenso a respeito dos widgets disponibilizados pelos toolkits (diferentes toolkits disponibilizam diferentes conjuntos de widgets), alguns deles oferecem ao usuário um conjunto razoavelmente vasto de widgets, tendo já implementado além de elementos de baixa complexidade, como push-buttons, elementos de complexidade mais elevada, como, por exemplo, text-boxes, list-boxes etc.

Tendo em vista os fatos apresentados acima, vemos que a possibilidade de incorporar ao conjunto de widgets implementados por TkVIX widgets provenientes de outros toolkits (os chamados widgets nativos) possui o sedutor atrativo de poupar o programador do esforço associado à sua implementação - esforço este que, como já vimos, pode ser considerável. Outra vantagem de se poder utilizar widgets nativos no toolkit, além da expansão do conjunto de widgets do toolkit e da incorporação de widgets complexos, é a adequação a um determinado look and feel. Esta característica pode vir a ser bastante atraente, a depender da plataforma: aplicações baseadas no sistema gráfico Xll, por exemplo, não possuem um look and feel padrão; como já vimos, embora o Motif tenha se tornado uma referência, a variedade de toolkits para construção de GUis, onde alguns implementam look and feel próprio, é razoável. Aplicações MS Windows, no entanto, p~uem essencialmente um look and feel padrão.

A incorporação de widgets nativos a TkVIX deve ser o mais homogênea possível, tanto a nível de funcionalidade e comportamento dos elementos de interface quanto a nível estético. Quanto maior o grau de homogeneidade, menos perceptível ao usuário final será o fato de ele estar lidando, em uma mesma interface, com elementos nativos e não-nativos.

Com o objetivo de facilitar a incorporação de widgets nativos ao framework, procu­rou-se definir uma arquitetura em que o framework implementa um conceito abstrato de widget nativo: existe um conjunto de atributos e operações que deverão ser implementadas por qualquer widget nativo incorporado ao sistema, e isto é tudo que o framework utilizará no gerenciamento destes widgets. Desta maneira, pretende-se que a incorporação de ·widgets nativos ao framework se dê através da ligação (linking) com os arquivos-objeto que possuam as implementações dos widgets nativos, sem que haja necessidade de re-

55

Page 69: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

compilação do framework em si. A nível de codificação, este conceito abstrato de widget nativo foi modelado pela

utilização do mecanismo de classes abstratas puras de C++. A classe VixNatWidget possui os serviços/atributos que devem ser comuns a todos os widgets nativos. Os serviços que puderam ser implementados neste nível de abstração o foram diretamente nesta classe; aqueles que são dependentes da implementação do widget nativo estão presentes sob a forma de métodos virtuais puros, devendo ser implementados à parte em alguma subclasse e incorporados ao framework na fase de ligação. Desta forma, o polimorfismo de C++ garante que o framework possa manipular widgets nativos sempre como objetos da classe VixNatWidget, quando na verdade se tratarão de objetos de subclasses desta, nas quais estarão implementados os métodos que nela são virtuais puros. A Figura 3.25 ilustra um exemplo de derivação de VixNatWidget, onde temos um ramo responsável por modelar os widgets Motif, e outro pelos widgets MS Windows.

ViXVO

Figura 3.25: Hierarquia de classes de widgets nativos

Através da Figura 3.25, podemos perceber a utilização da classe VixVO como super­classe dos widgets nativos; isto tem como objetivo fazer com que estes possam também ser tratados como objetos visuais VIX, a exemplo dos demais VOs por ele implementados.

Nossa "plataforma de testes" para incorporação de widgets nativos a TkVIX foi o toolkit Motif. Descreveremos a seguir como se deu esta incorporação, assim como seu impacto na arquitetura do sistema.

3.5.1 Widgets Motif

Por se tratar de uma classe abstrata pura, VlxNatWidget não pode ser instanciada. Faz­se necessário, portanto, que exista pelo menos um nível de derivação, modelando a classe dos widgets Motif; este requisito é atendido com a implementação da classe VixXmWidget. Como podemos constatar com o auxílio da Figura 3.25, todo widget Motif será, por sua vez, modelado por uma subclasse de ViximWidget.

A incorporação de widgets Motif ao framework teve um impacto inesperado e signi­ficativo na implementação de uma das camadas do framework: o Canvas Draw (CD). Esta afirmação sugere um contra-senso: sendo o CD uma biblioteca gráfica, que trata da exibição e manipulação de primitivas gráficas através de interação direta com o sistema

56

Page 70: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

gráfico nativo, como pode ser ele afetado pela inclusão, em um nível bem mais elevado de abstração, de objetos gráficos que não utilizam seus (CD) recursos gráficos? Este apa­rente contra-senso pode ser facilmente esclarecido, através da compreensão do real papel do CD no framework.

Quando, na Seção 2.2, explicamos o papel do CD, não o fizemos na sua totalidade. O CD, além de ser utilizado com a funcionalidade descrita, é responsável também por coletar os eventos gerados pelo usuário, assim como os eventos gerados pelo sistema gráfico que sejam relevantes para o funcionamento do framework ( desobscurecimento de janelas, re­dimensionamento das mesmas etc.). Para tal, foi criada para o framework uma versão especial do CD, denominada CD standalone {CDsa).

Os problemas advindos da incorporação de widgets Motif devem-se justamente ao fato do CD interagir diretamente com o sistema gráfico nativo: a coleta dos eventos é feita mediante utilização do loop de eventos do Xlib. O Motif, conforme vimos no Capítulo 2, é implementado sobre o Xlib e, devido a características particulares, possui seu próprio loop de eventos. O fato é que a utilização do loop de eventos do Xlib impossibilita a utilização de widgets Motif- estes simplesmente não conseguem ter acesso aos eventos, que são desviados para tratadores (handlers) situados em um nível mais baixo do sistema.

Para remediar esta situação, fez-se necessário o desenvolvimento de uma variante do CDsa, que possui como diferencial básico as seguintes características:

• utilizou-se o loop de eventos do Intrinsics (o mesmo utilizado pelo Motif}, e não o do Xlib;

• cada janela criada já possui um widget Motif associado a si: trata-se de um widget do tipo XmDrawingArea; isto se deve ao fato de ser este o widget de composição mais básico oferecido pelo Motif - uma drawing area possui filhos, mas não os impõe nenhuma política de layout. Portanto, na prática todo widget Motif instanciado pelo framework possuirá sempre como "ancestral primário" na hierarquia dinâmica a drawing area associada à janela em que se encontram; o usuário do toolkit, no entanto, não toma consciência da existência deste widget - tudo é gerenciado in­ternamente, de maneira transparente.

Esta variante do CDsa não vai de encontro à nossa filosofia de permitir a incorporação de widgets nativos ao framework sem que seja necessária a recompilação do mesmo: trata­se apenas de uma nova biblioteca, que deve substituir a do CDsa "tradicional" quando da ligação de aplicações que utilizem VIX com widgets Motif.

Outra característica relevante do Motif que teve impacto no framework é a maneira pela qual os eventos são tratados. No Motif, o enfoque é sobre callbacks, e não sobre o evento em si. Não existe, como no Xlib, um tratador global associado a cada evento, cada widget Motif corresponde a uma janela do sistema gráfico nativo, e os eventos são despachados diretamente para a janela ( widget) em que ocorreram; o tratamento de cada evento depende de o elemento que o recebe ter definido sua própria callback. O loop de eventos do Intrinsics se encarrega de enviar os eventos para os widgets a que se destinam; porém, isto é feito apenas para os widgets nativos. Assim, vemos que é preciso implemen­tar um mecanismo para garantir que eventos ocorridos sobre widgets não-nativos sejam a eles enviados, para permitir a coexistência de ambos os tipos de widgets em uma mesma

57

Page 71: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

interface. Isto é conseguido através da drawing area. O artifício utilizado consiste de fazer com que a drawing area, além de ser o primeiro widget da árvore de elementos, ocupe toda a área disponível do diálogo, atuando, portan.to, como um pano de fundo para todos os demais widgets, nativos ou não. Além disto, associamos à drawíng area tratadores para os eventos relevantes ao framework. Este, por sua vez, cadastra junto ao CDsa suas próprias callbacks para os eventos em que está interessado em processar (esta etapa é obrigatória, mesmo que não se utilize widgets nativos). Com esta configuração, fazemos com que os eventos que ocorram no diálogo, mas não sobre um widget nativo Motif instanciado pelo usuário, sejam tratados pela drawing a.rea, o que significará a execução das callbacks re­gistradas pelo framework. Desta maneira, garantimos que os widgets não-nativos recebam os eventos a eles direcionados através do framework, de maneira idêntica ao que ocorre quando não se utiliza widgets nativos.

O parágrafo anterior evidencia o mais sério obstáculo por nós encontrado à incorpo­ração dos widgets Motif ao VIX, que vem a ser o fato de que o Motif despacha auto­maticamente cada evento para a janela em que este ocorreu. Isto confere aos widgets Motif uma indesejada autonomia: VIX não tem como influir nos eventos dirigidos a estes widgets, o que inibe importantes funcionalidades do framework, como, por exemplo, a atuação de filtros. Em linhas gerais, o fato de widgets nativos serem também VOs (por ser VixNatWidget subclasse de VixVO) não possui efeito prático algum - os eventos não chegam a tais elementos através de VIX, mas sim através do Intrinsics. Como exemplo, imaginemos um grupo VIX que tem como ,particularidade suprimir os eventos de teclado dirigidos aos elementos nele contidos; tipicamente, o grupo simplesmente não repassa tais eventos para os seus filhos. Porém, sendo um de seus filhos um widget Motif, este receberá o evento antes que o grupo possa ter sobre ele alguma influência - na verdade, o grupo VIX nem tomará conhecimento do evento.

Apresentamos a seguir a solução implementada por TkVIX para contornar esta limi­tação imposta pelo tratamento de eventos realizado pelo Intrinsics. Em seguida, descre­veremos o processo de incorporação de um widget Motif a TkVIX, tomando como exemplo a caixa-de-texto.

Tratamento de eventos

Conforme colocado anteriormente, a política usual de tratamento de eventos implementa­da pelo lntrinsics constitui um sério obstáculo à homogeneização do tratamento dos wid­gets nativos e não-nativos. Visando contornar esta limitação, implementou-se em TkVIX um mecanismo especial para permitir que o framework trate qualquer evento, tenha este como destino um widget nativo ou não.

Antes de detalharmos o mecanismo implementado em TkVIX, cabe chamarmos a atenção para o fato de que widgets Motif possuem, por default, tratadores para uma série de eventos. Por exemplo, quando o usuário pressiona o botão esquerdo do mouse e o arrasta sobre um texto contido em uma text box, esta reage marcando o texto como selecionado. Para que estes widgets desempenhem seus papéis de acordo com o esperado, é fundamental que os eventos sejam processados por estes tratadores, na ordem correta.

A idéia básica do mecanismo de redirecionamento de eventos destinados a widgets nativos implementado por TkVIX é o cadastramento de um tratador de eventos, deno­minado eventTrap, para cada widget nativo instanciado pelo usuário, de maneira que

58

Page 72: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

este tratador seja executado antes dos tratadores defa.ult; este cadastramento é efetuado pelos construtores C++ dos VOs associados aos widgets Motif. Caso o evento recebido seja de um dos tipos de eventos nos quais o framework tem interesse, o tratador se en­carrega de redirecioná-lo à drawing area, executando o tratador por esta definido. Antes, porém, uma referência para o evento é armazenada, para posterior utilização, e é feita uma conversão de coordenadas, pois as coordenadas associadas ao evento são relativas à janela (widget) em que este ocorreu (ver Figura 3.26); a necessidade de se armazenar uma referência para o evento será justificada mais adiante.

X'

(o,0) 1

1 "

y• y 1

------------ ------X

wldget-pa/

Figura 3.26: Conversão de coordenadas entre widgets Motif. As coordena­das (x, y) dizem respeito ao wídget-füho, ao passo que as coor­denadas (x', y') são as mesmas coordenadas, porém relativas ao widget-pai

Ao executarmos o tratador de eventos da drawing area, estamos fazendo com que o evento seja enviado ao framework em cooi:idenadas relativas ao diálogo, de maneira idêntica ao que aconteceria se o sistema gráfico tivesse despachado o evento diretamente. Uma vez recebido pelo framework, o evento percorrerá a árvore de elementos até atingir o VO associado ao widget Motif sobre o qual ele ocorreu. Neste caminho, o evento está sujeito à ação de filtros, a exemplo de qualquer evento, podendo, portanto, sofrer alterações em seus parâmetros ou mesmo ser descartado. Caso o evento chegue até o "VO-Motif', este se encarregará de notificar ao CDsa tal fato, de modo que os tratadores default que eventualmente existam registrados no widget possam ser executados. Novamente, faz-se necessária nova conversão de coordenadas, desta vez no sentido inverso (da drawing area para o widget Motif). Conseguimos, através deste mecanismo, ilustrado pela Figura 3.27, permitir ao framework acesso aos eventos ocorridos sobre widgets Motif antes que estes possam tratá-los.

A notificação ao CDsa para que este prossiga com a execução dos tratadores default é feita através da função PutBackEvent, que recebe como argumentos o tipo do evento, o widget que deverá receber o evento e um número variável de argumentos relativos aos parâmetros do evento em questão; baseado no tipo do evento, é possível à função saber quantos e quais são estes argumentos. A função PutBackEvent, então, preenche uma estrutura do tipo cdEventlnfo e a envia ao CDsa através da função cdPutBackEvent; a estrutura cdEventinfo é utilizada por ser ela a representação utilizada pelo CDsa para comunicar a ocorrência de eventos às aplicações. A função cdPutBackEvent, por sua vez,

59

Page 73: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

.·············· .. ,,.,.,. (lntrlnlllt:•)

conVIJl'ÃO de coordenadn

! ........................................................... ~ /

ewnto~ 1 ~

converslo de

coordenada•

pelo frame"'1r : (wldget Afotlf)

1 ___________ .,

Figura 3.27: Modelo proposto para o tratamento de eventos destinados a widgets Motif

atualiza o evento interceptado por eventTrap com os dados recebidos do framework, e indica, através de um flag denominado shouldProceed, que o evento deverá ser processado também pelos tratadores default. Observar que, através deste mecanismo, permitimos que alterações sobre os parâmetros de um evento sofridas ao longo do percorrimento da árvore de elementos no framework sejam propagadas ao widget Motif.

O término da função cdPutBackEvent dará início ao processo que resultará no término da função eventTrap e, portanto, do tratamento do evento. Antes de encerrar sua exe­cução, eventTrap testa o valor do B.ag shouldProceed; caso este seja 1 (verdadeiro), a função simplesmente termina, o que fará com que o Intrinsics automaticamente execute os demais tratadores eventualmente cadastrados para o evento em questão. Caso o valor de shouldProceed seja O (falso), eventTrap indica ao Intrinsics que o tratamento do evento deve ficar a ela restrito. Como a única função que altera o valor de shouldProceed para verdadeiro é cdPutBackEvent, vemos que, caso esta não seja executada, indicando que o evento foi descartado durante o percorrimento da árvore de elementos no framework, eventTrap será o único tratador a processar o evento. A Figura 3.28 ilustra as situações descritas acima.

Da maneira como foi implementado, o mecanismo de interceptação de eventos desti­nados a widgets Motif garante que os eventos serão processados na ordem em que foram gerados, nos casos em que não há supressão de eventos por parte do framework. Observar que isto só é possível por ser TkVIX uma aplicação single-threaded, pois apenas assim podemos ter certeza de que eventos não são processados concorrentemente.

Convém aqui chamar atenção para o fato de deve-se evitar ao máximo a não-execução dos tratadores default dos widgets Motif. A literatura pesquisada relativa ao Intrinsics (1] faz sérias restrições a isto, afirmando que vários tratadores são registrados de modo a rea­lizar processamento interno necessário ao correto funcionamento dos widgets e do próprio

60

Page 74: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

encuta lnâdor da 4rawi111r&r•• . . . . . . . . . . . . . . . . . . . . . . . . . . . .. ntador de eventos • tlllollle:rooe•4 't.lllO enfio .., . . . . . . . . . . . . . . . . do fnlmeworlc

Inibe execuçlo dos rr.tadorn deteult : (1) 1 llm , ......................... .

(1) •bollldftoaeed • P&lH

(2) •bollldProaH4 • 'l'ru• : (2)

! ntlldor de eventos

do Vo-tlotlf

Figura 3.28: Interceptação de eventos destinados a widgets Motif

toolkit; a não-execução destes tratadores pode levar o Intrinsics a um estado incoerente. Desta forma, os desenvolvedores de aplicações, ao utilizar widgets Motif em conjunto com TkVIX, devem prestar especial atenção ao processamento realizado pelos filtros. Por exem­plo, a inibição de widgets Motif é potencialmente menos perigosa se conseguida através da execução de seus métodos Disable, em contraste com a estratégia de fazer com que filtros não repassem eventos para estes widgets.

Caso teste: incorporação de caixas-de-texto Motif

O primeiro passo para a incorporação de caixas-de-texto Motif ao framework consistiu da sua modelagem em C++. Isto foi feito através da definição da classe VixXm.TextField, derivada de VixXm.Widget que, por sua vez, é subclasse de VixNatWidget, conforme dis­cutido anteriormente. Muitos dos serviços esperados deste widget, como, por exemplo, desativação para interação com o usuário, ocultamento (hide) e consulta/atribuição de alguns dos seus atributos, como posição, dimensões e cor de fundo/frente, já se encontra­vam implementados pela classe VixXm.Widget, fazendo com que fosse necessária apenas a implementação de serviços específicos deste widget, tais como a recuperação/definição do texto nele contido.

Possuindo o text-box uma implementação C++, passamos à construção de um binding do mesmo com Lua. Esta etapa tem por finalidade permitir sua manipulação através da linguagem Lua, capacitando-o, portanto, a constar de descrições de interface escritas em Lua, da mesma maneira que os widgets não-nativos implementados no toolkit. A exemplo destes widgets, a construção do binding com Lua consiste essencialmente da sua modelagem no universo da linguagem, o que é conseguido através da implementação em Lua das classes e métodos pertinentes e do registro das funções C++ que terão como objetivo prover o elo de ligação entre as porções Lua e C++ do objeto. Assim, foi criada em Lua, a exemplo de C++, uma tabela associada à classe VixXm.Widget, que também não deve ser instanciada, servindo apenas de base para classes mais especializadas. Além de mapear em Lua os serviços oferecidos por VixXm.Widget em C++, esta tabela tem o importante papel de implementar os serviços esperados pelo toolkit de um widget Lua -

61

Page 75: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

essencialmente, métodos para permitir sua. manipulação por parte do algoritmo de Jayout abstrato.

Os wídgets Motif possuem ainda outra característica, além das já mencionadas: cada um deles deve estar associado a outro widget Motif, estando um deles obrigatoriamente na condição de widget-pai; esta é outra das razões para a existência das drawing areas mencionadas anteriormente. 4 Esta relação deve ser estabelecida quando da instanciação de cada widget pois, entre outras coisas, atributos não especificados pelo programador que não possuam valor default são herdados do wídget-pai. Esta necessidade por um widget­pai nos traz um problema de ordem prática: uma vez que não há a obrigatoriedade de, na descrição da interface, widgets Motif aparecerem sempre como filhos de outros widgets Motif (ver exemplo na Figura 3.29), faz-se necessário, quando da instanciação de um widget Motif, o percorrimento da hierarquia dinâmica, no sentido da sua raiz, em busca de outro widget Motif para assumir o papel de widget-pai; caso não seja encontrado nenhum, a própria raiz ( drawing area) assume este papel.

Figura 3.29: Combinação de widgets nativos e não-nativos. As caixas som­breadas representam os widgets nativos

A exemplo dos demais widgets do toalkit que possuem binding em Lua, para os quais existem funções específicas para troca de dados com C++ (ver Seção 3.4.2), criou­se também funções para permitir a troca de dados entre as implementações e++ dos widgets nativos e seus bindings com Lua. Implementou-se as funções LuaSetNatWidget e LuaGetNatWidget que, respectivamente, armazenam e recuperam de um objeto Lua o ponteiro void correspondente ao widget nativo criado em C++, ou seja, um obje­to da classe VixNatWidget. Além deste tipo de situação, existem ainda casos em que se deseja armazenar em Lua não um ponteiro para VixNatWidget, mas sim dados do próprio wídget nativo, como, por exemplo, um ponteiro do tipo Widget, definido pelo Motif como tipo básico para todos os widgets; para estas situações, foram criadas as funções LuaSetNatUserdata e sua contraparte, LuaGetNatUserdata. Obviamente, tags específicos foram criados para dar suporte a estas trocas de dados. Deve-se observar que o escopo de atuação destas funções não se restringe aos widgets Motif, estendendo-se a todo tipo de widget nativo que venha a ser incorporado ao framework.

Assim como as caixas-de-texto, outros widgets Motif foram incorporados a TkVIX; são eles a janela-de-texto (text window) e as listas de elementos (list-boxes). Janelas-de-

4Existem widgets Motif que não precisam possuir um pai, de modo que a hierarquia dinâmica de widgets possa possuir uma raiz. Como exemplo podemos citar os widgets do tipo TopLevelShell.

62

Page 76: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

texto são também caixas-de-texto, com a significativa diferença de não se estar restrito a apenas uma linha de texto; elas são criadas automaticamente com scrollbars horizontais e verticais, de modo a se poder ter acesso a todo o seu conteúdo. A Figura 3.30 apresenta uma janela-de-texto.

Text ,,iinctow · ' ~ 1 · :

Figura 3.30: Janela-de-texto

Listas de elementos são widgets que oferecem ao usuário um grupo de opções, sob a forma de strings, que podem ser selecionadas com o mouse ou o teclado. Pode-se permitir a visualização shnultânea de apen;is um subconjtJnto das opçoes disponíveis, caso em que são ·utilizadas scrollbars verticais para permitir acesso a todas as opções; scrollbars horizontais são utilizadas nos .casos .em que o tamanho :de um ou mais itens extrapola a largura da lista. Listas podem ser configu;rada.s de modo a.permitir a seleção de. múltiplos it-ens simultaneamente. Um diálogo contendo listas pode ser visualizado na Figura 3.21, exemplo .3.6.

É importante fris~r que a incorporação destes widgets Motif a TkVIX não implicou em manutenção no mesmo. As subçlasses foram definldas ~m arqúívos compilados à parte; as aplicações desenvolvidas çomo teste apenas tiveram que incluir os arquivos com as definições destas cl~es, assim como referenciar os arquivos-objeto correspondentes na fase de ligação.

63

Page 77: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Capítulo 4

Conclusão

O toolkit TkVIX foi concebido de modo a ser uma ferramenta de auxílio ao desenvolvimento de aplicações com interface gráfica que oferecesse recursos sofisticados de maneira simples e intuitiva. A análise de algumas das aplicações hoje disponíveis para este fim nos permitiu identificar aspectos que consideramos relevantes para fazer de TkVIX a ferramenta que idealizamos. Como consequência, incorporamos a TkVIX o suporte a Jayout abstrato, e utilizamos uma linguagem de configuração para descrição das interfaces.

O algoritmo para Jayout abstrato foi especialmente desenvolvido para TkVIX. Embora o modelo conceituai tenha sido o algoritmo empregado em IUP, o algoritmo implementado em TkVIX incorpora características que o tornam mais flexível: ele é capaz de lidar com elementos expansíveis em ambas as direções, e a distribuição de espaço entre os elementos considera prioridades associadas a estes pelo usuário. 1

A linguagem de configuração utilizada foi Lua, pelos motivos apresentados na seção 3.1. Com ela, conseguimos não apenas permitir a especificação da interface através de uma sintaxe simples, mas também disponibilizamos recursos tais como rápida prototipação, através do desenvolvimento da interface em separado da aplicação, e a possibilidade de se especificar parte do código da aplicação diretamente em Lua, de maneira integrada com a descrição da interface. Além deste seu emprego no sentido de simplificar a utilização de TkVIX, Lua foi também amplamente utilizada na implementação do próprio toolkit; como exemplo podemos citar o algoritmo para Jayout abstrato, que foi implementado inteiramente em Lua.

A utilização do paradigma de orientação a objetos, tanto em C++ quanto em Lua, possibilita um alto grau de reuso de código: foram definidos tipos básicos de widgets, que são especializados de acordo com as necessidades. É possível, inclusive, criar no­vos widgets exclusivamente em Lua, sem que seja necessário codificação em C++ (ver exemplo do widget round button, apresentado na Seção 3.2.1). Através da utilização de recursos da linguagem Lua, foi possível conferir ao toolkit a capacidade de manipular indiscriminadamente widgets C++ e Lua, caso isto se mostre necessário.

De modo a ampliar os recursos oferecidos por TkVIX, incorporou-se a este o suporte aos chamados widgets nativos , que vêm a ser widgets implementados por outros toolkits. O principal objetivo disto é evitar o esforço envolvido na implementação de widgets comple-

1 Até as primeiras versões operacionais do algoritmo de TkVIX, este era o panorama com relação a IUP. Hoje, porém, o algoritmo para Jayout abstrato de IUP já é capaz de lidar com elementos expansíveis.

64

Page 78: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

xos tais como listas de elementos ou caixas-de-texto. Especial cuidado foi empregado para que widgets nativos incorporados a TkVIX sejam utilizados da mesma maneira que o são os widgets não-nativos; desta forma, widgets nativos são criados e manipulados em Lua, e estão sujeitos às políticas de layout abstrato impostas por widgets de composição tais como hboxes e vboxes, além de coexistirem harmoniosamente com widgets não-nativos. Nenhum dos toolkits analisados para a confecção desta dissertação possibilitava tal inte­gração entre widgets nativos e não-nativos. Os widgets nativos incorporados como teste eram todos provenientes de um mesmo toolkit (Motif). Porém, tomou-se especial cuida­do para que, a nível do framework, este suporte se dê de forma genérica:· há o conceito abstrato de widget nativo, sem que este esteja vinculado a um determinado toolkit; os serviços esperados pelo framework/toolkit dos widgets nativos estão implementados como métodos virtuais puros, cabendo ao programador fornecer a implementação dos mesmos em subclasses de widgets nativos, implementadas em separado do toolkit. Com isto, widgets nativos podem ser implementados sob a forma de bibliotecas, que são ligadas às aplicações que deles necessitem, sem que haja necessidade de manutenção no toolkit (ver Seção 3.5.1). Espera-se, portanto, que a incorporação de widgets provenientes de outro toolkit que não o Motif possa ser feito de maneira análoga. 2

O conjunto de widgets não-nativos impleIJllentado teve como objetivo principal oferecer meios para testarmos o toolkit no que diz respeito a algumas de suas funcionalidades: fills, hboxes, vboxes e labels foram i~p\emellltados para testarmos o algoritmo de layout abstrato; botões foram implementados por se tratar de widgets básicos e simples que, no entanto, permitem o teste do comportamento dos V Os no que diz respeito a eventos ( enter, lea.ve, button press e button release); tound buttons foram implementados como teste da utilização do mecanismo de herança simples implementado em Lua para se definir um novo widget como especialização de outro widget também definido em Lua, sem que fosse necessária codificação em C++; menus horizontais fazem parte de experiências visando explorar as características do toolkit para a construção de widgets com comportamento não convencional. A possibilidade de se incorporar widgets nativos a TkVIX nos encoraja a manter um número reduzido de widgets não-nativos; porém, isto não impede que alguns outros, de implementação não muito rebuscada, como frames ou toggle buttons, venham a ser futuramente implementados. Outros recursos que ampliariam os recursos oferecidos pelo toolkit seriam, por exemplo, o tratamento de imagens por parte de alguns widgets e a implementação de um protocolo de drag and drop.

O uso de Lua como linguagem de configuração representa um importante aliado em uma possível linha de evolução do toolkit: existem trabalhos envolvendo o que se conven­cionou denominar "Lua distribuído" (22) - basicamente, código Lua pode ser executado em uma máquina por uma aplicação situada em outra máquina, estando as duas interli­gadas por uma rede; o código a ser executado pode ser inclusive enviado de uma máquina para a outra. Isto poderia ser aproveitado para incorporar ao toolkit suporte a objetos distribuídos; por exemplo, uma aplicação poderia alterar características de objetos ins­tanciados por outra aplicação remota, ou mesmo criar novos objetos remotamente. Para que este tipo de funcionalidade possa ser incorporado ao toolkit, um tratador dos eventos de rede teria de ser cadastrado junto ao CDsa; para tal, não se faz necessária manutenção

2Lembrar que pode vir a ser necessária também a. utilização de uma outra versão da biblioteca CDsa, como ocorreu no processo de incorporação de widgets Motif (ver Seção 3.5.1}.

65

Page 79: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

no CDsa, uma vez que este já possui rotinas para cadastro de tratadores de eventos. Testes neste sentido foram realizados durante o desenvolvimento de VIX, com resultados positivos.

A portabilidade do toolkit não foi efetivamente testada, mas a utilização de Lua e do CDsa constituem dois fatores positivos: ambas as bibliotecas possuem versão para diferen­tes plataformas UNIX-Jike, além dos sistemas operacionais da Microsoft para máquinas Intel. Quanto ao framework e ao toolkit, ambos foram implementados em C++, que possui compiladores para todas estas plataformas.3

TkVIX não é hoje um toolkit completo para construção de interfaces gráficas com o usuário; existem ainda aspectos a serem defi.Jllidos e/ou implementados antes que se possa considerá-lo uma ferramenta pronta para uso. Acreditamos, porém, ter estabelecido uma base sólida para que isso possa ser feito em trabalhos futuros.

3Testes no sentido de gerar uma versão do Eramework VIX para Microsoft Windows foram realizados durante seu desenvolvimento, com êxito.

66

Page 80: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Referências Bibliográficas

(1) Paul J. Asente and Ralph R. Swick. X Window System Toolkit. Digital Press, 1990.

[2] Marcelo Medeiros Carneiro. lnteract: um modelo de interação para editores gráficos. Dissertação de mestrado, Dep. Informática, PUC-Rio, Rio de Janeiro, Brasil, 1995.

[3) Steve Churchill. Fresco tutorial. C++ Report, 6{8):17-21, outubro 1994.

(4) Computer Vision Laboratory, Univeristy of Pa.via. Pavia's Active Component Com­pound Objects - A Tcl extension to manage binary objects. http://iride.unipv.it/pacco/docs/manual/pacco_toc.html,julho 1996.

(5) Matthew J. Conway, Randy Pausch, and Kimberly Passarella. A tutorial for SUIT -the Simple User Interface Toolkit. Relatório Técnico TR-90-29, University ofVirginia Computer Science Department, setembro 1990.

[6] A. Costa, A. Clinio, C. Cassino, and R. Ierusalimschy (Orientador). UAI - uma biblioteca gráfico-interativa portável orientada por objetos. Em XIII Concurso de Trabalhos de Iniciação Científica da SBC, páginas 767-775, Caxambu, 1994. {Menção Honrosa).

(7) André Luiz Soares Clinio dos Santos. VIX: Um framework para suporte a objetos visuais interativos. Dissertação de mestrado, Dep. Informática, PUC-Rio, Rio de Janeiro - RJ, Brasil, 1996.

[8J Waldemar C. Filho, Luiz H. Figueiredo, and Marcelo Gattass. EDG: Uma ferramenta para criação de interfaces gráficas interativas. Em SIBGRAPI 95, páginas 241-248, 1995.

[9) Open Software Foundation, editor. OSF/Motif Programmer's Guide. Prentice Hall, 1991.

(10] Donald E. Knuth. The fy)(Book. Addison-Wesley, 1984.

(11] Ioi K. Lam. Tix programmer's guide (version 4.0), 1996. http://www.xpi.com/tix/doc/documents.html.

[12] Carlos Henrique Levy, Luiz Henrique de Figueiredo, Marcelo Gattass, Carlos Lucena, and Don Cowan. IUP /LED: a portable user interface development tool. Software: Practice f3 Experience, 26(7):737-762, 1996.

67

Page 81: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

[13] M. Linton and C. Price. Building distributed user interfaces with Fresco. Em Proce­edings of the Seventh X Technical Conference, páginas 77-87, janeiro 1993.

[14] J. M. Vlissides M. A. Linton, P. R. Calder. Interviews: a C++ graphical interface toolkit. Relatório Técnico CSL-TR-88-3,58, Stanford University, 1988.

[15] Microsoft Corporation. Microsoft Visual Basic Programmer's Guide, 1995.

[16] John K. Ousterhout. Tcl: An embeddable command language. Em Winter 1990 USENIX Conference, 1990.

(17] John K. Ousterhout. An Xll toolkit based on the Tcl language. Em Winter 1991 USENIX Conference, 1991.

[18] John K. Ousterhout. Tcl and the Tk toolkit. Addison-Wesley, 1994.

[19] Chris D. Peterson. Athena Widget Set - C Language Interface. ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/Xaw/widgets.PS.Z.

[20] W. Ceies F. R. Ierusalimschy, L.H. de Figueiredo. Lua: an extensible extension language. Software: Practice & Experience, 26(6):635-652, 1996.

[21] Neil Armstrong Rezende. GLB: Uma ferramenta para manipulação de objetos gráficos procedurais. Dissertação de mestrado, Dep. Informática, PUC-Rio, Rio de Janeiro -RJ, Brasil, 1995.

[22] Noemi Rodriguez, Cristina Ururahy, Roberto Ierusalimschy, and Renato Cerqueira. The use of interpreted languages for implementing parallel algorithms on distributed systems. Em L. Bougé, P. Fraigniaud, A. Mignotte, and Y. Robert, editores, Euro­Par '96 Parallel Processing - Second International Euro-Par Conference, páginas 597-600, Volume I, Lyon, France, agosto 1996. Springer-Verlag. (LNCS 1123).

[23] The Santa Cruz Operation, Inc. SCO Visual Tcl Documentaion, 1995. http://www3.sco.com/Products/vtcl/doc/doc.html.

[24] Robert W. Scheifler and James Gettys. X Window System. Digital Press, 2g edição, 1990.

[25] TeCGraf - Grupo de Tecnologia em Computação Gráfica. GKS -- Manual de utilização e referência, versão 3. O, novembro 1989.

(26] TeCGraf - Grupo de Tecnologia em Computação Gráfica. INTGRAF - Manual de referência, agosto 1991.

[27] G. van Rossum. An introduction to Python for UNIX/C programmers. Em Proc. of the NLUUG najaarsconferentie. Dutch UNIX users group, 1993. ftp://ftp.cwi.nl/pub/python/nluug-paper.ps.

(28] T. C. Zhao and Mark Overmars. Forms library - A Graphical User Interface Toolkit for X, 1995. http://bragg.phys.uwm.edu/xforms.

68

Page 82: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

, ln dice

A árvore de elementos, 2 Athena Widget Set, 5

e Canvas Draw, 3, 22

e widgets Motif, 57 CD, veja Canvas Draw CD standalone, 5 7 CDsa, veja CD standalone

E EDG, 18 espaços visuais, 21 eventos

F

repaint, 35 resize, 37 widgets Motif

problemas, 57 solução, 58-61

filtros, 21 Fresco, 15

G graphical embedding, 15 grupos, 2

em VIX, 21 GUI, 1

1 Intrinsics, 6 IUP, 17 IUP/Lua, 19

L layout abstrato, 2

69

Athena Widget Set, 7 Fresco, 16 Motif, 9 SUIT, 15 Tk, 11 TkVIX, veja TkVIX, layout abstrato Visual Basic, 13 XForms, 10

layout concreto, 2 LED, 17 Lua,4, 24

características, 19, 24 construtores, 32 fallbacks, 25

e objetos c++, 52 tipos básicos, 24

M Motif, 8

o object embedding, 13 objetos visuais, 21

p prioridades, 33, 39

exemplo, 41

s SUIT, 14

T Tcl, 11 Tk, 11 TkVIX

elementos expansíveis, 33 exemplos, 41-50

Page 83: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

especificação da interface, 30 integração Lua ~ C++, 51-53 layout abstrato, 26, 33, 38

toolkit, 1

u UIL, 10 usuário final, 5

V Visual Basic, 13 VisualTcl, 12 VIX, 4, 20

mensagens, 23, 52

w widgets, 1

X

Button, 27, 41, 43, 46-48 Canvas, 28, 41 de composição, veja grupos Dialog, 27, 43, 46-48 em TkVIX, 26 Fill, 27, 41, 43, 46, 48 Hbox, 27, 47, 48 HorMenu, 28 Item, 28 Label, 28, 45, 46 nativos, 3, 47, 48, 55, 64 RButton, 28 Vbox, 27 Xmlist, 48, 62 XmTextField, 47, 61 XmTextWindow, 62

XForms, 10 Xlib, 5

70

Page 84: TkVIX - UM TOOirKIT PARA CONSTRUÇÃO DE EM LUAwebserver2.tecgraf.puc-rio.br/~mgattass/teses/1997DissertacaoAndre... · DE INTERFACES GRÁFICAS EM LUA DISSERTAÇÃO DE M ESTRADO 0

Tk VIX - Um Toolkit para Construção de Interfaces Gráficas em Lua

Dissertação de Mestrado apresentada por André Oliveira da Costa, no dia 24 de abril de 1997, ao Departamento de Informática da PUC-Rio e aprovada pela Comissão Julgadora, formada pelos seguintes professores:

~~+-d: Departamento de Informática - PUC-Rio

Pr . Marcelo Gattass De artament de Informática- PUC-Rio

Departamento de Informática - PUC-Rio

Visto e permitida a impre~são1 Rio de Janeiro, f O de 9<-·<JW:/VlO de 1997.

'l Coo denador dos Programas de Pós-Graduação e

Pesquisa do Centro Técnico Científico