4D dispõe de funções integradas que lhe permitem arrastar e soltar objetos em seus formulários e aplicações. É possível arrastar e soltar um objeto sobre outro, localizado na mesma janela ou em outra. Em outras palavras, pode arrastar e soltar ao interior de um processo ou entre diferentes processos.
Igualmente pode arrastar e soltar objetos entre formulários 4D e outras aplicações e vice-versa. Por exemplo, é possível arrastar e soltar um arquivo de imagem GIF em um campo imagem 4D. Também é possível selecionar texto em uma aplicação de processamento de palavras e soltá-la em uma variável de texto 4D.
Finalmente, é possível soltar objetos diretamente na aplicação sem ter que necessariamente um formulário de fundo. O Método banco de dados On Drop pode ser utilizado para administrar a ação de arrastar e soltar neste caso. Isto significa, por exemplo, que pode abrir um documento 4D Write soltando-o no ícone da aplicação 4D. Esta implementação específica é descrita na págian Método banco de dados On Drop
4D oferece dois modos de arrastar e soltar:
um modo personalizado, onde o programador maneja toda a operação de arrastar e soltar. Este modo lhe permite implementar qualquer interface baseada em arrastar e soltar, incluidas as interfaces que não necessariamente transportam dados, mas que podem realizar qualquer ação como abrir arquivos ou desencadear um cálculo. Este modo se baseia em uma combinação de propriedades, eventos e comandos específicos do tema “Área de Transferência (Pasteboard)”. um modo automático, onde uma operação de arrastar e soltar copia ou movimenta automaticamente os dados de um objeto a outro. Este modo está disponível para objetos baseados em texto e (parcialmente) imagens, e pode ser habilitado simplesmente ao verificar uma propriedade. Este modo se detalha na seção Arrastar e soltar automáticos a seguir.
Implementar uma interface personalizada de arraster-e-soltar significa combinar propriedades, eventos e comandos do tema “Área de Transferência (Pasteboard)” O diagrama abaixo ilustra os pontos principais para criar uma sequência personalizada de arrastar-e-soltar:
Sua implementação será baseada nos cenários abaixo:
No evento On Drag Over do objeto destino (com propriedade "Droppable"), obtém os tipos de dados ou assinaturas de dados encontradas no pasteboard usando GET PASTEBOARD DATA TYPE ou GET PASTEBOARD DATA e checa se são compatíveis com o objeto destino. O comando Drop position retorna o número de elementos da posição de item do elemento alvo ou item da lista, se o objeto destino for um array (ou seja, uma área rolável), uma lista hierárquica, um texto ou uma combo box, assim como o número de coluna se o objeto for uma list box. Se o objeto destino ou elemento for compatível, retorna 0 em $0 para aceitar o soltar, senão retorna -1 em $0.
No evento On Drop do objeto destino ("com propriedade "Droppable"), executa qualquer ação em resposta ao drop. Se a operação arraster-e-soltar tiver a intenção de copiar os dados arrastados, simplesmente atribua os dados ao objeto destino. Se o arrastar e soltar não tiver a intenção de mover dados, mas sim uma metáfora de interface de usuário para uma operação em particular, pode realizar o que quiser, pro exemplo, obter rotas de arquivo usando o comando Get file from pasteboard.
Todas essas propriedades e eventos estão detalhados abaixo.
Para arrastar e soltar um objeto sobre outro objeto, deve selecionar a Propriedade arrastável para esse objeto na janela da Lista de propriedades. Em uma operação arrastar e soltar, o objeto que é arrastado é o objeto fonte.
Para fazer que um objeto seja soltável, ou seja, que o objeto possa ser o destino de uma operação de arrastar e soltar, deve selecionar a propriedade soltável para esse objeto na Lista de propriedades. Em uma operação arrastar e soltar, o objeto que recebe os dados é o objeto de destino.
Nota: as propriedades adicionais Arrastar automático e Soltar automático estão disponíveis para campos e variáveis de tipo texto, combo boxes e list boxes. A opção Soltar automático também está disponível para campos e variáveis tipo imagem. Podem ser utilizadas para ativar um modo arrastar e soltar automático baseado em copiar o conteúdo (a ação arrastar e soltar já nos é administrada pelos eventos de formulário 4D). Por favor consulte o parágrafo Arrastar e soltar automáticos ao final desta seção.
Automaticamente os objetos criados recentemente não possuem nenhuma destas propriedades. É sua decisão selecionar estas propriedades.
Todos os objetos em um formulário de entrada, ou em um diálogo, podem ser definidos como arrastáveis e soltáveis. Os elementos individuais de um array (por exemplo, uma área de rolagem), os elementos de uma lista hierárquica ou as filas em uma list box podem ser arrastáveis e soltáveis. Pelo contrário, pode arrastar e soltar um objeto sobre um elemento individual de um array ou de uma lista hierárquica ou uma linha de um list box. Entretanto, não pode arrastar e soltar objetos da área de detalhe de um formulário de saída.
Igualmente pode administrar arrastar e soltar na aplicação, fora de todos os formulários, utilizando o Método de banco de dados On Drop
Facilmente pode criar uma interface de usuário arrastar e soltar, porque 4D lhe permite utilizar todo tipo de objeto ativo (campo ou variável) como objetos fonte ou de destino. Por exemplo, pode arrastar e soltar um botão.
Notas:
Para arrastar um texto ou um botão que tenha a propriedade "arrastável," primeiro deve pressionar a tecla Alt (Windows) ou Opção (Mac OS).
Automaticamente, no caso de campos e variáveis de imagem, a imagem e sua referência sâo arrastados. Se só deseja arrastar a referência da variável ou campo, primeiro pressione a tecla Alt (Windows) ou Opção (Mac OS).
Quando em um objeto de tipo List box, as propriedades “Arrastável” e “Filas moveis” estão definidas simultaneamente, a propriedade “Filas moveis” tem prioridade quando uma fila é movida. Neste caso não é possível arrastá-lo.
Um objeto que é arrastável e soltável também pode ser soltável em si mesmo, a menos de que recuse a operação. Para mais detalhes, consulte os parágrafos seguintes.
A seguinte imagem mostra a janela da Lista de propriedades com as propriedades Arrastável e Soltável definidas para o objeto selecionado:
A gestão de arrastar e soltar por programação está baseada em três eventos de formulário: On Begin Drag Over, On Drag Over e On Drop.
Note que o evento On Begin Drag Over gera no contexto do objeto fonte de arrastar enquanto On Drag Over e On Drop são enviados ao objeto de destino unicamente.
Para que a aplicação processe estes eventos, devem ter sido selecionados de uma forma adequada na Lista de Propriedades:
O evento de formulário On Begin Drag Over é selecionável para todos os objetos de formulário que possam ser arrastados. É gerado em todos os casos onde o objeto tenha a propriedade Arrastável. Pode ser chamado a partir do método de objeto fonte ou o método formulário do objeto fonte.
Nota: A diferença do evento de formulário On Drag Over, On Begin Drag Over é chamada dentro do contexto do objeto fonte da ação arrastar.
Este evento é útil para a gestão avançada da ação arrastar. Pode ser utilizado para:
Adicionar os dados e as assinaturas na área de transferência (pelo comando APPEND DATA TO PASTEBOARD) Usar um ícone personalizado durante a ação arrastar (via o comando SET DRAG ICON).
Aceitar ou recusar ou arrastar através de $0 no método do objeto arrastado. Para indicar que a ação arrastar é aceita, o método do objeto fonte deve devolver 0 (zero); portanto deve executar $0:=0. Para indicar que as ações de arraste são recusadas, o método ou o objeto fonte deve devolver -1 (menos 1); você deve portanto executar $0:=-1. Se não retorna o resultado, 4D considera que o arrastar é aceito.
Os dados de 4D são colocados na área de transferências antes de chamar ao evento. Por exemplo, no caso de arrastar sem a ação Arrastar automático, o texto arrastado já está na área de transferências quando se chamar o evento.
O evento On Drag Over é enviado repetidamente ao objeto de destino quando o ponteiro do mouse é movido sobre o objeto. Em resposta a este evento, você geralmente:
Obtem os dados e assinaturas encontradas na área de transferência (via o comando GET PASTEBOARD DATA).
Dependendo da natureza e tipo do objeto de destino (cujo método de objeto está sendo executado) e o objeto fonte, você aceita ou recusa o arrastar e soltar.
Para aceitar arrastar, o método do objeto de destino deve retornar 0 (zero), de maneira que você escreve $0:=0. Para recusar ou arrastar, o método de objeto deve retornar -1 (menos uno), de maneira que escreve $0:=-1. Durante um evento On Drag Over, 4D trata o método do objeto como uma função. Se não retorna nenhum resultado, 4D assume que se aceita arrastar.
Se aceitar o arrastar, o objeto de destino é ativa. Se o recusar, o objeto de destino permanece inativo. Aceitar o arrastar não significa que os dados arrastados sejam inseridos no objeto de destino. Só significa que se o botão do mouse foi liberado neste ponto, o objeto de destino aceitaria os dados arrastados.
Se não processa o evento On Drag Over para um objeto soltável, o objeto é destacado para todas as operações de arrastar, sem importar a natureza e tipo dos dados arrastados.
O evento On Drag Over lhe permite controlar a primeira fase de uma operação de arrastar e soltar. Não só pode provar se o tipo dos dados arrastados é compatível com o objeto de destino e depois aceitar ou recusar o arraste; pode simultaneamente notificar ao usuário dessa ocorrência, porque 4D ativa ou não o objeto de destino, em função de sua decisão.
O código que trata um evento On Drag Over deve ser curto e ser executado rapidamente, porque o evento é enviado repetidamente ao objeto atual de destino, devido aos movimentos do mouse.
O evento On Drop é enviado ao objeto de destino (uma só vez) quando o cursor do mouse é liberado sobre o objeto. Este evento é a segunda fase da operação arrastar e soltar, na qual você realiza uma operação em resposta à ação do usuário.
Este evento não é enviado ao objeto se o arrastar não foi aceito durante os eventos On Drag Over. Se processar o evento On Drag Over para um objeto e recusa um arrastar, não ocorre o evento On Drop. Se durante o evento On Drag Over você provou a compatibilidade de tipos de dados entre os objetos fonte e destino e aceitou um possível soltar, não necessita provar novamente os dados durante On Drop. Você já sabe que os dados são compatíveis com o objeto de destino.
Um aspecto interessante da implementação de arrastar e soltar é que 4D lhe permite fazer o que você queira. Exemplos:
Se um elemento de uma lista hierárquica é solto sobre um campo de tipo texto, você pode inserir o texto do elemento da lista ao começo, ao final, ou na metade do campo de texto.
Seu formulário contém um botão de imagem de dois estados, o qual representa uma lata de lixo vazia ou cheia. Soltar um objeto sobre esse botão poderia significar (desde o ponto de vista de la interface do usuário) “suprimir o objeto que foi arrastado e soltado na canastra.” Aqui, arrastar e soltar não transporta dados de um ponto a outro; ao invés disso, realiza uma ação.
Arrastar um elemento de um array de uma janela flutuante a um objeto em um formulário poderia significar “mostrar nesta janela o registro do cliente cujo nome você acaba de arrastar e soltar desde a janela flutuante listando os clientes armazenados no banco de dados”.
Etc.
A interface de arrastar e soltar de 4D é um framework que lhe permite a qualquer usuário implementar todas as metáforas de interface de usuário que você possa imaginar.
As áreas de texto (campos, variáveis, combo boxes e list boxes) como também objetos de imagem permitem o arrastar e soltar automático, ou seja o movimento ou cópia de uma seleção de texto ou imagem de uma área a outra em um só clique. Pode ser utilizada na mesma área 4D, entre duas áreas 4D, ou entre 4D e outra aplicação, por exemplo WordPad.
Nota: no caso de arrastar e soltar automático entre duas áreas 4D, os dados são movidos, em outras palavras, são eliminados da área fonte. Se deseja copiar os dados, mantenha pressionado Ctrl (Windows) ouOpção (OS X) durante a ação (sob OS X, deve pressionar a tecla Opção logo de iniciar arrastar os elementos).
O arrastar e soltar automático pode ser configurado separadamente para cada objeto de um formulário através de de duas opções da Lista de propriedades: Arrastar automático e Soltar automático.
Arrastar automático: (objetos de tipo texto unicamente): quando esta opção estiver selecionada, o modo arrastar automático é ativado para o objeto. Este modo é prioritário para as imagens, inclusive se a opção Arrastável estiver selecionada. Neste modo, o evento de formulário On Begin Drag Over NÃO é gerado.Se deseja "forçar" a uilização de arrastar padrão, pressione a tecla Alt (Windows) ou Opção (OS X) durante a operação (sob OS X, deve pressionar a tecla Opção logo de iniciar arrastar os elementos). Esta opção não está disponível para imagens.
Soltar automático: Esta opção é utilizada para ativar o modo soltar automático. Neste modo, 4D maneja automaticamente, se possível, a inserção de dados arrastados de tipo texto ou imagem e soltados no objeto (os dados são colados no objeto). Os eventos de formulário On Drag Over e On Drop não são gerados neste caso. No caso de soltar dados diferentes de texto ou imagens (outro objeto 4D, arquivo, etc. ) ou dados complexos, a aplicação se refere ao valor da opção Soltável: se estiver selecionada, são gerados os eventos de formulário On Drag Over e On Drop; caso contrário, é recusado o soltar. Isto também depende do valor da opção "Proibido soltar dados que não provenham de 4D" (ver a continuação).
A partir da versão 11, 4D permite o arrastar e soltar de seleções, de objetos, ou de arquivos externos a 4D, como por exemplo os arquivos de imagens. Esta possibilidade deve ser compatível pelo código do banco.
Nos bancos convertidos de uma versão anterior de 4D, esta possibilidade pode levar ao malfuncionamento se o código existente não estiver adaptado. Por essa razão, uma opção nas Preferências pode ser utilizada para desativar esta função: Proibido soltar dados que não provenham de 4D.
Esta opção é encontrada na página Aplicação/Compatibilidade. Está selecionada automaticamente nos bancos convertidos.
Quando esta opção estiver selecionada, é recusada o soltar objetos externos em formulários 4D. Note entretanto que a inserção de objetos externos continua sendo possível em objetos que tenham a opção Soltar automático, quando a aplicação pode interpretar os dados soltados (texto ou imagem).
// Object Method: label1 If(FORM Event=On Drop) //Exige que Droppable Action esteja ativada na lista Property ARRAY TEXT($signatures_at;0) ARRAY TEXT($nativeTypes_at;0) ARRAY TEXT($formatNames_at;0) GET PASTEBOARD DATA TYPE($signatures_at;$nativeTypes_at;$formatNames_at) If(Find in array($signatures_at;"com.4d.private.text.native")#-1) // há texto 4D na área de transferência (pasteboard) OBJECT Get pointer(Object current)->:=Get text from pasteboard End if End if
Combinar propriedades de arrastar e soltar, automáticas e personalizadas, permite interfaces simples e poderosas. Neste exemplo, se quisermos preencher uma área de texto com dados arrastados de uma list box:
List box: propriedade "Draggable" e evento "On Begin Drag Over" estão marcadas
Se quiser que o usuário selecione um arquivo no disco, e então arraste e solte-o em uma variável "enterable" [pode ser editável] (do tipo objeto) para que possa exibir uma descrição de arquivo json.
Se quiser que o usuário selecione arquivos no disco, e então arraste e solte-os em uma list box de modo que exiba as rotas de arquivo:
No método de objeto list box, pode escrever:
C_LONGINT($0) Case of
:(Form event code=On Drag Over) // Aceitar evento On Drop apenas se o pasteboard conter arquivos, senão rejeitar. If(Get file from pasteboard(1)#"") //pelo menos um arquivo foi soltado $0:=0 //aceitar drop Else//nenhum arquivo no pasteboard $0:=-1 //rejeitar drop End if
:(Form event code=On Drop) //Exije ação Droppable ativada da Lista de Propriedade ARRAY TEXT(importedPath_at;0) C_TEXT($path_t) C_LONGINT($index_l) $index_l:=1 Repeat $path_t:=Get file from pasteboard($index_l) If($path_t#"") APPEND TO ARRAY(importedPath_at;$path_t) End if $index_l:=$index_l+1 Until($path_t="") End case