Algumas
vezes nos deparamos com desafios incríveis, no Delphi:
resolver determinadas questões que implicam no uso de recursos
simples, modestos e tão óbvios que, exatamente por
estas “qualidades”, não constam de nenhuma bíblia,
curso, apostila ou mesmo de listas de discussão. A sua
simplicidade termina por inibir perguntas, afinal ninguém
quer passar atestado de desconhecimento do óbvio.
Pensando
nisso, resolvemos reproduzir aqui uma conversa “acontecida” entre
dois de nossos mais importantes colaboradores: Batman e Sobrinho.
Batman, como todos sabem, é o eterno professor de Sobrinho,
que não esconde seu deslumbramento em relação
à programação Delphi. Vamos à ela...
Batman,
preciso de um favor: não estou conseguindo fazer uma rotina
para traçar figuras a mão livre (ou mouse livre),
no estilo dos antigos editores gráficos. Algo como o velho
Paint do Windows já dava para quebrar um galho.
Não sei nem por onde começar.
Ora
sobrinho, comece sempre pelo começo. É o melhor
jeito de resolver as coisas.
Ta,
mas onde é o começo? Que componente eu uso? Qual
dos componentes gráficos é melhor?
Sobrinho,
de um modo geral, todos os componentes são bons. Para coisas
gráficas, você precisa usar algum que tenha canvas.
O canvas nada mais é do que a superfície (em bits)
gráfica. Antigamente chamávamos de “tela”, então,
quem tem um canvas, tem uma tela só para ele (o componente)
e que geralmente é do mesmo tamanho que o próprio
componente.
O
Timage tem canvas, o TPaintBox tem também,
o TBItMap idem e o Form1 também tem seu próprio
canvas. Tudo o que serve para um canvas, serve para outro, pois
todos são derivados do objeto TCanvas.
Então,
se você quer traçar uma reta entre a coordenada 0,0
e a posição atual do mouse, use no evento OnMouseDown
a seguite linha de programação:
Canvas.MoveTo(0,0); Canvas.LineTo(X, Y); |
Santa
programação Batman, só isso?
É
sobrinho, se só quiser desenhar uma reta entre dois pontos,
é tudo o que tem a fazer. Agora, se quer emendar uma linha
na outra, concatenando-as a cada clique do mouse, faça
o seguinte:
Crie
duas constantes globais:
const
Px: integer = 0;
Py: integer = 0; |
A
seguir, mude a programação do evento OnMouseDown
para:
Canvas.MoveTo(Px,Py); Canvas.LineTo(X, Y);
Px:= x; Py:= y; |
Hummm!
Entendí. E como faço para mudar a espessura da linha?
Heim? Heim? Heim?
Essa
é fácil, sobrinho:
Com
isso você já pode criar um programa (as crianças
vão adorar) como aquelas antigas brincadeiras de emendar
pontos numerados em sequência (lembra delas, sobrinho)?
Mas, se quer fazer um programa para traço “a mouse livre”,
como você disse, então use o evento OnMouseMove,
ao invés do OnMouseDown. E para só desenhar
enquanto o botão esquerdo do mouse estiver pressionado,
faça:
if ssLeft in Shift then begin
Canvas.Pen.Width:= 2;
Canvas.MoveTo(Px,Py); Canvas.LineTo(X, Y);
Px:= x; Py:= y;
end; |
Batman,
para mudar a cor seria:
Canvas.Pen.Color:= clBlue; |
Isso
sobrinho, está “pegando o jeito da coisa”.
E
para desenhar um círculo? Como eu faria, heim Batman?
Calma
sobrinho, não queira passar o carro adiante dos bois. Você
ainda nem sabe desenhar um retângulo e já quer desenhar
um círculo? Primeiro aprenda o que é mais fácil.
Por exemplo, para preencher uma figura que acabou se desenhar,
com uma determinada cor:
if ssRight in Shift then begin
Canvas.Brush.Color:= clGreen;
Canvas.FloodFill(x,y,clBlue,fsBorder);
end; |
Se
colocar esse pedaço de programação num evento
OnMouseDown, então acompanhe o que acontecerá:
Canvas.Brush.Color será a cor usada para “pintar”
e clBlue (dentro do FloodFill, será a cor limite
(sua cor azul).
Santos
preenchimentos de áreas Batman, já posso fazer meu
editor gráfico de última geração...
Calma
sobrinho, ainda é cedo para isso. Ainda não aprendeu
como fazer uma linha elástica, não é mesmo?
Para isso usaremos algo já visto aqui na TILT,
que é transferência de áreas gráficas.
Com isso podemos montar um buffer de tela. Acompanhe o raciocínio:
crie um TBitmap global...
Nos
eventos OnCreate e OnDestroy do Form1 coloque:
procedure TForm1.FormCreate(Sender: TObject);
begin
Buffer:= TBitmap.Create;
Buffer.Width:= Form1.ClientWidth;
Buffer.Height:= Form1.ClientHeight;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Buffer.Free;
end; |
No
evento OnMouseDown escreva:
Px:= x; Py:= y;
Buffer.Canvas.CopyRect(rect(0,0,Buffer.Width,Buffer.Height),
Canvas,rect(0,0,Buffer.Width,Buffer.Height)); |
Isso
fará com que uma cópia do desenho seja arquivada
no buffer. A seguir faça, no evento OnMouseMove:
if ssLeft in Shift then begin
Canvas.Pen.Width:= 4; Canvas.Pen.Color:= clBlue;
Canvas.Draw(0,0,Buffer);
Canvas.MoveTo(Px,Py); Canvas.LineTo(X, Y);
end; |
O
resultado será uma linha que é “esticada” até
seu ponto de “ancoragem”. Fácil, rápido e sem burocracia.
Santas
linhas elásticas, Batman, com isso já posso arrasar
no editor gráfico.
Mas
sobrinho, e o resto?
Ora
Batman, alguma coisa eu quero descobrir sozinho como fazer. Senão
você faz toda a parte divertida da programação,
não é mesmo? |