Desenhar linha indicativa durante o quot;Drag and Dropquot

10/03/2006

0

Pessoal,

Tudo começa com vários RadioButtons espalhados pelo form. Quero fazer um código para fazer um drag and drop entre dois RadioButtons. O usuário clica no primeiro, mantém o botão pressionado, e arrasta o ponteiro do mouse até o segundo RadioButton onde ele solta o botão do mouse. Bem, O ´Drag And Drop´ eu sei fazer, mas queria melhorar um pouco. Queria que a partir do momento que o usuário pressionar o botão do mouse e arrastar uma linha fosse desenhada de modo que ela se iniciasse do meio do RadioButton onde o ´Drag and Drop´ começou e terminasse sempre no local onde o ponteiro do mouse aponta. De modo que conforme o usuário for movendo o mouse a linha deve se mover junto.

Possivelmente essa linha será desenhada no Canvas do form, certo?
Mas como pegar o ponto do meio do RadioButton Inicial e como fazer para ao mover o mouse a linha ser atualizada?

Grato pela atenção!


Delphi32

Delphi32

Responder

Posts

10/03/2006

Adriano Santos

Pessoal, Tudo começa com vários RadioButtons espalhados pelo form. Quero fazer um código para fazer um drag and drop entre dois RadioButtons. O usuário clica no primeiro, mantém o botão pressionado, e arrasta o ponteiro do mouse até o segundo RadioButton onde ele solta o botão do mouse. Bem, O ´Drag And Drop´ eu sei fazer, mas queria melhorar um pouco. Queria que a partir do momento que o usuário pressionar o botão do mouse e arrastar uma linha fosse desenhada de modo que ela se iniciasse do meio do RadioButton onde o ´Drag and Drop´ começou e terminasse sempre no local onde o ponteiro do mouse aponta. De modo que conforme o usuário for movendo o mouse a linha deve se mover junto. Possivelmente essa linha será desenhada no Canvas do form, certo? Mas como pegar o ponto do meio do RadioButton Inicial e como fazer para ao mover o mouse a linha ser atualizada? Grato pela atenção!



Cara, não sei exatamente como fazer, mas imagino.
Pegar o centro do TRadioGroup basta fazer um calculo de acordo com o Heigth e Width do mesmo. +/- assim:

var  
  xLeft, xTop : Integer;
begin
  xTop := (RadioGroup.Heigth div 2);
  xLeft := (RadioGroup.Width div 2);
  QualquerObjeto.Left := xLeft;
  QualquerObjeto.Top := xTop;
end;

Ou seja, daria para desenhar algo no ´centro´ do RadioGroup usando as coordenadas Left e Top gravadas nas variaveis xLeft e xTop, não sei se fui claro.

Agora desenhar com canvas? Num sei, porque a atualização do mesmo conforme movimentação do mouse teria que ficar apagando e redesenhando no Canvas, apagar eu não sei como faz.

Acredito que eu faria com o TShape bem ´fininho´ pra dar a aparencia de linha.


Responder

10/03/2006

Delphi32

Nesse espaço de tempo eu consegui evoluir um pouco.
Adicionei o seguinte código:

procedure TForm1.RadioButton1DragDrop(Sender, Source: TObject; X,
  Y: Integer);
begin
   Form1.Canvas.Pen.Color := clMaroon;
   Form1.Canvas.Pen.Width := 2;
   with TRadioButton(Source) do
   Form1.Canvas.MoveTo( Left, Top );
   with TRadioButton(Sender) do
   Form1.Canvas.LineTo( Left, Top );
end;


O problema é que esse código faz com que a linha seja desenhada somente quando o usuário soltar o botão do mouse. Ainda não sei como fazer para a linha acompanhar o ponteiro do mouse.

Adriano, quando eu vi seu post, já tinha conseguido fazer a linha com esse código acima. De qualquer maneira, obrigado pela ajuda!

E tem outro detalhe também. Nesse código o desenho da linha fica por trás do RadioGroup. Tem como fazer com que ela fique por cima do RadioGroup?

t+!


Responder

10/03/2006

Delphi32

Com a ajuda de alguns códigos que encontrei pela internet, quase consegui fazer o que eu quero. Tá quase funcionando! Vou colocar o código e depois explicar o problema:

var
  Form1: TForm1;
  PrimeiraLinha, IsDragging: Boolean;
  OldX, OldY, OrigemX, OrigemY: Integer;

implementation

{$R *.dfm}

procedure TForm1.RadioButton1DragOver(Sender, Source: TObject; X,
  Y: Integer; State: TDragState; var Accept: Boolean);
begin
   Accept := (Sender is TRadioButton) and (Sender<>Source);
end;

procedure TForm1.RadioButton1DragDrop(Sender, Source: TObject; X,
  Y: Integer);
begin
   IsDragging := False;
   primeiralinha := True;
   //
   Form1.Canvas.Pen.Color := clMaroon;
   Form1.Canvas.Pen.Width := 3;
   with TRadioButton(Source) do
   Form1.Canvas.MoveTo( Left, Top );
   with TRadioButton(Sender) do
   Form1.Canvas.LineTo( Left, Top );
end;

procedure TForm1.RadioButton1StartDrag(Sender: TObject;
  var DragObject: TDragObject);
begin
   PrimeiraLinha := True;
   OrigemX := TRadioButton(Sender).Left;
   OrigemY := TRadioButton(Sender).Top;
   IsDragging := True;
end;

procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
   if IsDragging then
   begin
      if not PrimeiraLinha then
      begin
         Form1.Canvas.Pen.Color:=clBlack;
         Form1.Canvas.Pen.Width:=1;
         Form1.Canvas.MoveTo(OrigemX,OrigemY);
         Form1.Canvas.LineTo(OldX,OldY);
      end
      else Form1.Canvas.Pen.Mode:=pmNotXor;
      //
      Form1.Canvas.Pen.Color := clBlack;
      Form1.Canvas.Pen.Width := 1;
      Form1.Canvas.MoveTo(OrigemX,OrigemY);
      Form1.Canvas.LineTo(X,Y);
      OldX:=X;
      OldY:=Y;
      PrimeiraLinha := False;
   end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   IsDragging := False;
   PrimeiraLinha := True;
end;

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   IsDragging := False;
end;


Os problemas são os seguintes:

Se eu clico o botão e arrasto para o segundo RadioButton a linha não aparece. Aparece somente a ´linha final´.

Se eu clico uma vez e solto em cima do mesmo RadioButton e depois arrastar o mouse, a linha que eu quero aparece seguindo exatamente o ponteiro do mouse, mas eu queria que ela aparecesse enquanto o botão do mouse estivesse pressionado e estivesse no meio de uma operação de ´Drag and Drop´. Está funcionando mais ou menos ao contrário e eu não estou encontrando o lugar para acertar...

Um outro problema é que se eu ficar arrastando o mouse em volta do form, começam a aparecer pontos pretos na tela. Como se o Canvas não estivesse ´apagando´ corretamente. Coloquei entre aspas porque como se pode ver no código, para dar a impressão de apagar é pintado por
cima uma outra linha e como a Pen está com ´Mode=pmNotXor´ fica a impressão de apagado.

Bem, se alguém puder me ajudar, eu agradeço.

O projeto pode ser baixado em:
[URL]http://www.geocities.com/delphirj/draganddrop.zip[/URL]

Ps.: Consegui evoluir nesse código graças a um artigo na net sobre como fazer um relógio analógico somente com canvas. Mesmo com o fonte do projeto não estou conseguindo fazer... A url do artigo é:
[URL]http://www.digitalcoding.com/programming/delphi/tutorial/tuteg17.htm[/URL]

t+!


Responder

13/03/2006

Delphi32

Galera, descobri a fonte do meu problema. O problema é que depois que eu chamo BeginDrag e antes de chamar EndDrag, o evento MouseMove não está sendo executado.

Como fazer para que o BeginDrag não anule o evento OnMouseMove?
Alguma idéia de como proceder?

t+!


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar