10 de novembro de 2009

Customizando a aparência de um Grid em Delphi - parte 2

Continuando o post anterior, sobre como customizar a aparência de grids em Delphi, mostro aqui exemplos práticos dessa customização.

Os parâmetros aceitos pelo evento OnDrawCell num StringGrid são mostrados abaixo.
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);

Este evento é disparado uma vez para cada célula do Grid que precisar ser desenhada. Além do tradicional Sender (que representa o próprio grid que está gerando o evento), o evento também trás a linha e coluna que identifica qual é a célula desenhada. O parâmetro Rect indica um retângulo dentro do Canvas cujas coordenadas delimitam a célula a ser desenhada, isto é, é o espaço do Canvas reservado para o desenho da Célula indica pelos parâmetros ACol, ARow. O último parâmetro - State - é um conjunto de indicadores que sinalizam condições especiais para o desenho da célula. São estados tais como se a célula está selecionada ou não, se está com o foco para entrada de dados e se está numa das linhas ou colunas fixas do Grid.

Antes de prosseguir com a inclusão de código como resposta a esse evento, vou modificar a propriedade DefaultDrawing do StringGrid para False. Isso avisa a VCL que nós estamos assumindo o controle do desenho das células e que a VCL não deve executar as suas rotinas internas associadas à exibição dos dados de cada célula. Isto dito, segue um exemplo de resposta padrão para modificar as cores apresentadas no texto de um stringGrid:
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var yCalc : integer;
Texto : String;
lCanvas : TCanvas;
begin
{ Salva em variáveis locais por questão de clareza do código }
texto := StringGrid1.Cells[ACol, ARow];
lCanvas := StringGrid1.Canvas;

if gdFixed in State then begin
{ Cor do fonte e de fundo para linhas e colunas fixas }
lCanvas.Font.Color := clBlack;
lCanvas.Brush.Color := StringGrid1.FixedColor;
end else
if gdSelected in State then begin
{ Cor do fonte e de fundo para linhas e colunas selecionadas }
lCanvas.Font.Color := clWhite;
lCanvas.Brush.Color := clHighlight;
end
else begin
{ Cor do fonte e de fundo para linhas e colunas com dados }
if ACol mod 2 = 0 then
lCanvas.Font.Color := clBlue { azul nas colunas pares}
else
lCanvas.Font.Color := clRed; { vermelho nas ímpares }
lCanvas.Brush.Color := StringGrid1.Color;
end;

{ Preenche com a cor de fundo }
lCanvas.FillRect(Rect);

{ Calcula posição para centralizar o texto na vertical }
yCalc := lCanvas.TextHeight (texto);
yCalc := Rect.Top + (Rect.Bottom - Rect.Top - yCalc) div 2;
lCanvas.TextRect (Rect, Rect.Left + 3, yCalc, texto);
end;

Seguem algumas considerações sobre o trecho acima. A primeira coisa a observar é que grande parte do código é dedicada a configurar as propriedades do Canvas - o Brush para pintar a cor de fundo da célula e a Font para determinar a cor do texto. Algumas dessas configurações consideram o "Estado" da célula, isto é, se ela está selecionada ou se é parte da linha e coluna fixa. Poderia ainda ter levado em consideração também qual é a célula que está com foco e dar-lhe algum destaque.

O outro objeto disponível (Pen) não é alterado neste exemplo mas poderia ter sido caso quiséssemos desenhar linhas com características distintas. Isso inclui a borda da célula. Repare apenas que o Rect passado no parâmetro não considera a borda da célula, de modo que teríamos que expandir manualmente este retângulo caso quiséssemos aplicar uma cor ou espessura diferente à borda.

Uma coisa importante a ressaltar é que o Grid em si possui uma propriedade Font cuja configuração é usada como padrão para desenhar os textos, ou seja, o que configuramos nela é repassado para o Canvas antes da pintura do Grid iniciar. Modificar a Font do Grid, então, dispara a pintura do componente como um todo - e não de uma célula específica. Por isso, alteramos diretamente a fonte do Canvas no evento de pintura da célula, evitando que novos eventos de pintura sejam gerados eternamente.

No exemplo, as colunas pares são escritas em azul e as ímpares em vermelho. Claro que faria mais sentido interpretar o texto da célula e aplicar-lher cores mais adequadamente.

A linha de código lCanvas.FillRect(Rect) usa as configurações feitas no Brush para pintar o fundo da célula antes de aplicarmos o texto associado a ela. O comando lCanvas.TextRect (Rect, Rect.Left + 3, yCalc, texto) usa as configurações de fonte do Canvas para desenhar o texto da célula centralizado na vertical em relação ao retângulo reservado para a célula.

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.