Reordenação de Items em ListBox
Eu tenho uma tabela que contém itens ordenados. A coluna “posicao” indica a posição relativa de cada item (de 1 a n) e seus valores não podem ser repetidos. Eu precisava de uma forma prática de redefinir a ordenação dos itens. A dificuldade é que a cada vez que um item muda de posição todos os itens posteriores também devem mudar.
A solução foi levar todos os nomes de itens para um TListBox respeitando a ordenação atual e deixar o usuário livremente posicionar os nomes sem se preocupar com o dataset. Quando o usuário estiver satisfeito com a ordem dos itens, clica em OK e o programa atribui de uma só vez todos os valores de “posicao” ao dataset conforme os índices dos nomes no ListBox. Read more
Teclas Enter e Esc no Delphi
Se você veio aqui procurando uma dica sobre como aceitar tecla ENTER para mudar de campo, não perca seu tempo porque não vai encontrar (se depois de ler esse artigo você ainda quiser, tenho certeza que o Google vai mostrar um zilhão de técnicas).
As convenções existem por um motivo: estabelecer um entendimento comum entre as partes sobre alguma coisa. Se uma das partes (no caso, a aplicação ou o usuário) ignorar a convenção a coisa não funciona.
A regra é clara: a tecla para pular de um campo é TAB, não ENTER.
Quem estabeleceu a regra não fui eu, foi a indústria ao longo dos anos. A publicação em 1987 pela IBM do manual Common User Access (CUA) foi um marco importante. A Microsoft seguiu essa cartilha no desenvolvimento da interface de usuário do Windows, até porque ajudou a criá-la durante a fase de cooperação do OS/2 com a IBM. Hoje em dia a Microsoft tem padrões mais atualizados que cobrem novos aspectos do Windows XP e do Windows Vista, como acessibilidade, bitmaps de alta definição, cores, transparências, interação com dispositivos USB, etc.
Quando os fabricantes de teclados colocam o mesmo conjunto de teclas de suporte, como Home, End, Insert, Delete, Tab, F1 a F12 e Print Screen, também estão respeitando as convenções da indústria.
A tecla ENTER tem um papel bem definido em caixas de diálogo, que é confirmar a aceitação do conteúdo e fechar a janela. Ou seja, equivale a um clique no botão OK. Similarmente a tecla ESC fecha a janela cancelando os dados, equivalendo a um clique no botão Cancelar.
TButton.Default, OK?
Por ser uma convenção, a API do Windows suporta nativamente desde a sua primeira versão essas de teclas de atalho em caixas de diálogo. Você não precisa fazer nada para que as combinações TAB e Shift+TAB mudem o foco dos controles. O que muita gente não sabe é que a API também trata nativamente ENTER e ESC.
A biblioteca VCL do Delphi torna tudo muito mais simples. Basta usar as propriedades tipo Boolean Default e Cancel de TButton para aceitar as teclas ENTER e ESC, respectivamente.
Definir TButton.Default = True faz mais que aceitar a tecla ENTER. Desenha um botão diferenciado, com a borda mais destacada, o que indica visualmente ao usuário qual é o botão padrão que será acionado ao se teclar ENTER.
Para o usuário acostumado a usar teclado, é extremamente conveniente (necessário até, eu diria) que a tecla ESC (TButton.Cancel = True) também seja tratada para sair da janela sem salvar nenhum dado.
Exceções
Exceções existem, é claro. Uma tela de entrada de dados de grande volume, ainda mais se os usuários nem sempre têm os olhos voltados para o teclado ou se a entrada é basicamente numérica, é uma possível candidata. Sem dúvida é mais fácil digitar com a mesma mão direita o ENTER (o TAB fica à esquerda) e porque as teclas ENTER (as duas!) são sempre maiores e verticais, facilitando o operador “acertar” a digitação sem olhar.
Outra justificativa comum é que os usuários estão acostumados a usar um programa antigo para DOS e são habituados a usar ENTER. Na minha opinião não é uma boa desculpa. É a hora de ensinar a convenção que todo mundo usa. Quando esses mesmos usuários navegarem na Internet vão ter que usar TAB para mudar de campo e ENTER para confirmar um formulário de qualquer forma.
Não podemos perder de vista que é a exceção não é a regra. A convenção é nossa amiga. A convenção facilita a vida do usuário e do desenvolvedor.
Modelos de interface SDI, MDI, TDI e NDI
Os programadores que viveram a época do modo texto em DOS tinham desafios bem diferentes ao projetar uma interface de usuário. Independente da linguagem utilizada - fosse Clipper, C, Pascal, FoxPro ou qualquer outra - as escolhas eram basicamente o melhor sistema de menu e a melhor combinação de caracteres de linha e cores de fundo e texto para diagramar as telas de 80 linhas por 25 colunas.
Na década de 90 os programadores descobriram a interface MDI (”Multiple Document Interface”) no Windows. Achavam o máximo aquele monte de janelas superpostas. Como o Delphi tornava muito fácil criar esse tipo de interface, qualquer programinha tinha múltiplas janelas flutuando na área cliente e não faltavam aquelas famigeradas opções de janelas em cascata, lado-a-lado, minimizadas, etc. A gente se sentia até orgulhoso de fazer um sistema com interface semelhante à do Office. Melhor ainda se os ícones fossem os mesmos da Microsoft.
O que nós desenvolvedores ignorávamos então é que os usuários finais não dão a mínima pra nada disso. Os usuários gostam de fazer uma coisa de cada vez, com início, meio e fim. Lidar com várias janelas abertas na mesma aplicação só torna mais confuso o trabalho.
Muitos se assutaram quando o próprio Office, que havia popularizado o modelo MDI, abandonou a estratégia. A Microsoft fez muitas pesquisas de opinião e laboratórios de usabilidade para chegar a conclusão que não valia a pena insistir naquilo. Ficamos perdidos em busca de um novo modelo de interface de usuário.
A alguns anos veio com o FireFox e outros navegadores modernos a inspiração para uma idéia salvadora: apresentar janelas em páginas selecionáveis por abas. Definiu-se um novo modelo, que alguns chamam de TDI (”Tabbed Document Interface”), em oposição ao antigo MDI. As janelas abertas (documentos) são fáceis de visualizar e selecionar. Cada aba utiliza grande parte da área cliente, dando ao usuário a confortável sensação que está sempre trabalhando com uma janela “maximizada”.
É fácil, no entanto, observar que os usuários finais preferem. O mais simples e direto modelo de interface é o mais eficaz. Muitas vezes os mais complexos modelos de interação acabam reduzidos pela forma com que o usuários utilizam a um modelo simples de uma única janela que ocupa toda área do monitor, conhecido como SDI (”Single Document Interface”).
A propósito, qual seria o modelo de interface de um sistema web? Pense no Americanas.com, no Orkut e no site do seu supermercado favorito. Não é TDI, nem MDI, evidentemente. Cada página funciona na mesma área cliente, alternando-se conforme o opção escolhida pelo usuário. O que mais se aproxima é o bom e velho SDI.
Todos esses modelos de interface têm uma coisa em comum: o conceito de documento. Seja um documento de texto, uma planilha eletrônica ou uma página web, todos os documentos são da mesma natureza em uma interface MDI, TDI ou SDI.
Ainda hoje, por falta de opção ou por retrógrada herança da cultura de modo texto dos anos 80 muitos desenvolvedores ainda utilizam uma grande tela vazia (ou pior, um imenso bitmap espalhafatoso com o logo da empresa no fundo), um menu e uma barra de botões no topo da janela e mais nada. Esse modelo é o que se pode chamar NDI: “No Document Interface”. A cada opção de menu, abre-se uma caixa de diálogo diferente. Pode não ser bonito ou elegante, mas é funcional. Os clientes entendem.
O fato é que os usuários imediatamente absorvem a metáfora do menu que abre e fecha opções e volta ao estado inicial. Dá até para imaginar um usuário ensinando a outro como usar a aplicação: “Escolhe essa opção para cadastrar e essa outra para tirar um relatório…”.
Janelas e Documentos
Trazer o conceito de documentos para um cliente nativo Windows não é fácil. Pelo menos, não é óbvio. Aplicações de negócio têm relatórios, telas de cadastro, consulta e configuração e lidam com grupos de informação diferentes (clientes, produtos e vendas, por exemplo), cada um com uma forma de apresentação própria.
Na busca de um modelo orientado a documentos, seja TDI ou mesmo SDI, torna-se necessário definir um tipo abstrato de objeto que possa representar todos os tipos de telas que se deseje apresentar na aplicação, similar ao conceito de documento dos browsers e editores de texto.
O Delphi não traz nada disso pronto, mas oferece inúmeros recursos que possibilitam a sua implementação. A chave é a programação orientada a objetos. Veja bem, eu disse programação, não interface orientada a objetos.
Uma hierarquia de classes de forms é chamada “herança visual” na VCL. Podemos usar herança visual para definir um form base que implemente o conceito de documento numa interface TDI ou SDI.
É razoável que todos os forms documento tenham alguma funcionalidade em comum. Todos os “documentos” podem ser abertos (abrir datasets, iniciar controles), fechados (fechar datasets, liberar objetos de memória), copiar para clipboard (seja um TEdit ou um TChart) e muitos até impressos. Esses são exemplos de ações comuns. Outras, no entanto, não podem ser abstraídas sem prejuízo de entendimento. Por exemplo, “Calcular” não é um bom candidato para uma ação comum, porque não é natural calcular um cadastro, por exemplo.
Há várias formas de implementar funções específicas de um tipo de documento: botões direto na janela, objetos TAction integrados em um TActionList global, menu merge, etc.
Balancear o que deve ser abstraído e o que deve ser especializado é sutil. Isso vale, é bem verdade, para todos os modelos de representação hierárquica e orientada a objetos, de modelos de dados a interfaces de usuário. Felizmente, no caso das interfaces de usuário você sempre tem o recurso de sair da sua mesa e ir perguntar os maiores interessadods, os usuários: “Para você, o que é melhor?”.
