Drag and Drop – Kaban – em Delphi

Drag and Drop - Kaban - em Delphi
Kaban

Introdução

Nesse post iremos ver um exemplo de uso dos eventos de Drag and Drop (arrasta e solta) do Delphi. Drag and Drop – Kaban – em Delphi. Esse exemplo poderá ser utilizado para criar um quadro tipo Kanban, que pode ser utilizado para organizar a fazeres do dia a dia ou do trabalho.

Explorando a Propriedade DragMode e os Eventos OnDragDrop e OnDragOver no Delphi

O Delphi é uma ferramenta poderosa para o desenvolvimento de aplicações ricas e interativas, e um dos recursos mais úteis para criar interfaces dinâmicas é o suporte a drag-and-drop. Este recurso permite que os usuários arrastem objetos ou dados de uma parte da aplicação para outra, oferecendo maior interatividade e flexibilidade. Neste artigo, vamos explorar como usar a propriedade DragMode e os eventos OnDragDrop e OnDragOver no Delphi.


Entendendo a Propriedade DragMode

No Delphi, a propriedade DragMode é usada em conjunto com o mecanismo de arrastar e soltar. Ela define o comportamento do componente ao receber um item durante a operação de drag-and-drop. Normalmente, você configurará a propriedade DragMode de um componente para dmAutomatic ou dmManual, o que determina se ele responderá automaticamente ou exigirá intervenção do desenvolvedor.

  • dmAutomatic: O componente entra automaticamente no modo de arrastar quando o usuário inicia uma operação de drag-and-drop.
  • dmManual: Exige que você inicie explicitamente a operação usando o método BeginDrag.

Evento OnDragOver

O evento OnDragOver é acionado continuamente enquanto o usuário arrasta um item sobre o componente. Ele é usado para validar se o destino aceita ou não o item que está sendo arrastado.

Estrutura do Evento

procedure(Sender: TObject; Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean) of object;
  • Sender: O componente que está recebendo o evento.
  • Source: O componente que iniciou a operação de arrastar.
  • X, Y: Coordenadas do ponteiro do mouse no momento.
  • State: O estado atual do arraste (dsDragEnter, dsDragLeave, dsDragMove).
  • Accept: Um valor booleano que indica se o componente aceita o item arrastado.

Exemplo de Uso

No exemplo abaixo, o componente destino aceita apenas objetos arrastados de um componente específico:

procedure TForm1.Panel1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
begin
  Accept := Source is TButton; // Aceita apenas botões
end;

Evento OnDragDrop

O evento OnDragDrop é acionado quando o usuário solta o objeto arrastado sobre o componente. Aqui você implementa a lógica para manipular o item que foi arrastado e definir como ele será tratado.

Estrutura do Evento

procedure(Sender: TObject; Source: TObject; X, Y: Integer) of object;
  • Sender: O componente que está recebendo o evento.
  • Source: O componente que iniciou o arraste.
  • X, Y: Coordenadas do mouse no momento em que o item é solto.

Exemplo de Uso

No exemplo abaixo, um botão é movido para um novo painel quando solto:

procedure TForm1.Panel1DragDrop(Sender, Source: TObject; X, Y: Integer);
begin
  if Source is TButton then
  begin
    TButton(Source).Parent := TPanel(Sender); // Move o botão para o novo painel
    TButton(Source).Left := X;
    TButton(Source).Top := Y;
  end;
end;

Passo a Passo: Implementando Drag-and-Drop no Delphi

No exemplo abaixo iremos demonstrar como mover painéis de um lado para o outro, como se fosse um Kanban.

  1. Arraste 5 painéis(TPanel) para o form principal. Três painéis serão utilizados como containers e dois painéis serão utilizados como tarefas.
  2. Configuração do Componente de Origem:
  • Defina a propriedade DragMode como dmAutomatic.
  • Adicione eventos de suporte, como OnMouseDown para iniciar o arraste se estiver usando dmManual.

      3. Configuração do Componente de Destino:

    • Adicione o evento OnDragOver para validar se o objeto pode ser solto.
    • Adicione o evento OnDragDrop para manipular a lógica de soltar o item.

          4. Implementação no Código: Configure os eventos no código ou no Object Inspector.

      Código Completo

      unit Unit1;
      
      interface
      
      uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
        Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls;
      
      type
        TForm1 = class(TForm)
          Panel1: TPanel;
          pnlToDo: TPanel;
          pnlTask1: TPanel;
          pnlTask2: TPanel;
          pnlInProgress: TPanel;
          pnlDone: TPanel;
      
          procedure FormCreate(Sender: TObject);
          procedure panelContainerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
          procedure panelContainerDragDrop(Sender, Source: TObject; X, Y: Integer);
          procedure panelTaskDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
        private
          FDraggingPanel: TPanel;
          procedure InitializeKanban;
        public
        end;
      
      var
        Form1: TForm1;
      
      implementation
      
      {$R *.dfm}
      
      procedure TForm1.FormCreate(Sender: TObject);
      begin
        InitializeKanban;
      end;
      
      procedure TForm1.InitializeKanban;
      begin
        // Configuração inicial dos painéis que servirão de containers
        pnlToDo.Caption := 'To Do';
        pnlInProgress.Caption := 'In Progress';
        pnlDone.Caption := 'Done';
      
        // Configuração inicial dos painéis de tarefas
        pnlTask1.Caption := 'Task 1';
        pnlTask2.Caption := 'Task 2';
      
        //Configurar os painéis para o modo de arrasto automático
        pnlTask1.DragMode := TDragMode.dmAutomatic;
        pnlTask2.DragMode := TDragMode.dmAutomatic;
        pnlToDo.DragMode := TDragMode.dmAutomatic;
        pnlInProgress.DragMode := TDragMode.dmAutomatic;
        pnlDone.DragMode := TDragMode.dmAutomatic;
      
        //Configurar os eventos de arrastar sobre dos painéis
        pnlTask1.OnDragOver := panelTaskDragOver;
        pnlTask2.OnDragOver := panelTaskDragOver;
        pnlToDo.OnDragOver := panelContainerDragOver;
        pnlInProgress.OnDragOver := panelContainerDragOver;
        pnlDone.OnDragOver := panelContainerDragOver;
      
        //Configurar os eventos de arrastar e soltar dos painéis
        pnlToDo.OnDragDrop := panelContainerDragDrop;
        pnlInProgress.OnDragDrop := panelContainerDragDrop;
        pnlDone.OnDragDrop := panelContainerDragDrop;
      end;
      
      procedure TForm1.panelContainerDragDrop(Sender, Source: TObject; X, Y: Integer);
      begin
        FDraggingPanel.Align := alBottom; //configura o painel para se alinhar no fundo - essa configuração fará com que as tarefas fiquem ordenadas uma embaixo da outra, ao arrastar
        FDraggingPanel.Parent := TPanel(Sender); //configura o novo pai do painel tarefa
        FDraggingPanel.Align := alTop; //configura o painel para se alinhar ao topo - essa configuração fará com que as tarefas fiquem ordenadas uma embaixo da outra, ao arrastar
      
        FDraggingPanel := nil //Limpa a variável que recebe o  painel que representa a tarefa.
      end;
      
      procedure TForm1.panelContainerDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
      begin
        Accept := (Sender is TPanel); //Configura os painéis que serão os containers para aceitar outros painéis
      end;
      
      procedure TForm1.panelTaskDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
      begin
        if Sender is TPanel then
        begin
          FDraggingPanel := TPanel(Sender); //Seta a variável FDraggingPanel para receber o painel que representa a tarefa.
        end;
      end;
      
      end.

      Para ver o funcionamento basta clicar em cima dos painéis “Task 1” ou “Task 2” e arrastar e soltar para os painéis “To Do”, “In Progress” ou “Done”.

      Veja abaixo a ilustração do projeto:

      Drag and Drop - Kaban - em Delphi
      Ilustração do Projeto.

      Código fonte do exemplo

      Você pode fazer o download do exemplo do projeto através do repositório do github:

      https://github.com/Gisele-de-Melo/Drag-and-Drop


      Dicas Práticas

      1. Validação no OnDragOver: Use o parâmetro Accept para evitar comportamentos inesperados, validando os componentes que podem ser arrastados.
      2. Organização Visual: Ao soltar o item, ajuste sua posição para evitar sobreposição ou desalinhamento.
      3. Customização: Combine drag-and-drop com efeitos visuais, como mudanças na cor do componente destino ao aceitar um objeto.

      Conclusão

      Os eventos OnDragOver e OnDragDrop oferecem uma base poderosa para implementar interatividade no Delphi, permitindo criar interfaces intuitivas e dinâmicas. Seja para construir um Kanban, um editor visual ou qualquer aplicação que requeira movimentação de componentes, o suporte a drag-and-drop no Delphi é uma solução elegante e eficaz.

      Com essas dicas e exemplos, você está pronto para explorar ainda mais o potencial dessa funcionalidade e criar aplicações ricas em funcionalidades para seus usuários.

      Posts Relacionados

      Deixe um comentário