Array
(
)

Desenhar linha indicativa durante o quot;Drag and Dropquot

Delphi32
   - 10 mar 2006

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!


Adriano Santos
   - 10 mar 2006


Citação:
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:

#Código


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.


Delphi32
   - 10 mar 2006

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

#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+!


Delphi32
   - 10 mar 2006

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:

#Código


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+!


Delphi32
   - 13 mar 2006

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+!