Desenhar linha indicativa durante o quot;Drag and Dropquot
10/03/2006
0
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
Posts
10/03/2006
Adriano Santos
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.
10/03/2006
Delphi32
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+!
10/03/2006
Delphi32
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+!
13/03/2006
Delphi32
Como fazer para que o BeginDrag não anule o evento OnMouseMove?
Alguma idéia de como proceder?
t+!
Clique aqui para fazer login e interagir na Comunidade :)