Recent

Author Topic: [SOLVED] Stringgrid alignments and background color  (Read 3976 times)

barsoom

  • Jr. Member
  • **
  • Posts: 51
[SOLVED] Stringgrid alignments and background color
« on: July 28, 2021, 08:54:52 pm »
On the first hand, i want to have the text of the cells (except first row and column) centered.  To do it, i select the column in the object inspector, and set its "Alignment" to tacenter, as proposed here by @wp here:
https://forum.lazarus.freepascal.org/index.php?topic=34285.0
It works perfect.

However, i also want to add color to each independant column (except first column and row), while keeping the center alignment of the text. I use this piece of code on "OnDrawCell" event:
Code: Pascal  [Select][+][-]
  1. procedure TForm6.SunGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  2.   aRect: TRect; aState: TGridDrawState);
  3. var
  4.   ts: TTextStyle;
  5. begin
  6.   if (ACol = 3) and (ARow >= 1) then
  7.     with TStringGrid(Sender) do
  8.     begin
  9.       Canvas.Brush.Color := $7FFFD4; //Testing color
  10.       Canvas.FillRect(aRect);
  11.       Canvas.TextOut(aRect.Left+2,aRect.Top+2,Cells[ACol, ARow]);
  12.       Canvas.Font.Color := clBlack;
  13.       ts := Canvas.TextStyle;
  14.       ts.Alignment := taCenter;
  15.       Canvas.TextStyle :=ts;
  16.     end
  17.   else if (ACol = 4) and (ARow >= 1) then
  18.     with TStringGrid(Sender) do
  19.     begin
  20.       Canvas.Brush.Color := clSkyBlue; //Testing color
  21.       Canvas.FillRect(aRect);
  22.       Canvas.TextOut(aRect.Left+2,aRect.Top+2,Cells[ACol, ARow]);
  23.       Canvas.Font.Color := clBlack;
  24.       ts := TStringGrid(Sender).Canvas.TextStyle;
  25.       ts.Alignment := taCenter;
  26.       TStringGrid(Sender).Canvas.TextStyle :=ts;
  27.     end;
  28.  
  29. end;                        

The color adjusment works perfectly, but not the aligment, since the text is left aligned in spite it was configured as centered in the object inspector, and that i included specific call to change it in the above code. BTW, you can see that i did in two different ways in each column in the code above, just to try to see if this could solve it.... nop!

The second issue is that when i select a row, the standard colored rows changes to a grey color, however, those cell on the modified columns keep the new color. How could i do to color all the selected cell in the same row show a blue color (instead of the grey one)?

I added a capture of the form on runtime to see the effects of these code.

Thanks!!
« Last Edit: July 29, 2021, 08:08:23 pm by barsoom »

winni

  • Hero Member
  • *****
  • Posts: 3197
Re: Problems with stringgrid alignments and background color
« Reply #1 on: July 28, 2021, 09:25:33 pm »
Hi!

If you draw the cell on your own then you have to do the whole stuff you asked

* selected color

In  aState is the state of the the cell. So ask if the cell is selected:

Code: Pascal  [Select][+][-]
  1. if gdSelected in aState then StringGrid1.Canvas.Brush.Color:= clred else StringGrid1.Canvas.Brush.Color:= clAqua;
  2.  
   


* center text:

You should not ask that if you align the text to the left:

Code: Pascal  [Select][+][-]
  1. Canvas.TextOut(aRect.Left+2,aRect.Top+2,Cells[ACol, ARow]);

You have to center the text on your own:

Code: Pascal  [Select][+][-]
  1. var s: string;
  2. dx: integer;
  3. ...
  4. s := StringGrid1.Cells[aCol,aRow];
  5. dx := (aRect.Right - aRect.Left - StringGrid1.Canvas.TextWidth(s)) div 2;
  6. StringGrid1.Canvas.TextOut(arect.Left+dx,arect.top +2,s);    
  7.  


Got it?

Winni

barsoom

  • Jr. Member
  • **
  • Posts: 51
Re: Problems with stringgrid alignments and background color
« Reply #2 on: July 28, 2021, 09:30:10 pm »
I think i got it, thanks a lot @Winni.
I will try it!
Thanks!!

wp

  • Hero Member
  • *****
  • Posts: 11830
Re: Problems with stringgrid alignments and background color
« Reply #3 on: July 28, 2021, 09:38:16 pm »
You draw the text with Canvas.TextOut, but this does not respect the Canvas.TextStyle where you specify the Alignment. You must use Canvas.TextRect instead.

Simply for selecting a cell color and alignment there is another way which does not require you to draw the cell yourself. There is an event OnPrepareCanvas which fires immediately before the cell is drawn. Whatever you apply to the canvas here will be used in the drawing step.

In order to determine whether a cell is selected you must check the aState parameter.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
  2.   aState: TGridDrawState);
  3. var
  4.   grid: TStringGrid;
  5.   ts: TTextStyle;
  6. begin
  7.   grid := (Sender as TStringGrid);
  8.   if (ACol = 3) and (ARow >= grid.FixedRows) then
  9.   begin
  10.     if aState * [gdSelected, gdFocused] <> [gdSelected, gdFocused] then
  11.       grid.Canvas.Brush.Color := $7FFFD4;
  12.     ts := grid.Canvas.TextStyle;
  13.     ts.Alignment := taCenter;
  14.     grid.Canvas.TextStyle := ts;
  15.   end else
  16.   if (ACol = 4) and (ARow >= grid.FixedRows) then
  17.   begin
  18.     if aState * [gdSelected, gdFocused] <> [gdSelected, gdFocused] then
  19.       grid.Canvas.Brush.Color :=clSkyBlue;
  20.     ts := grid.Canvas.TextStyle;
  21.     ts.Alignment := taCenter;
  22.     grid.Canvas.TextStyle := ts;
  23.   end;
  24. end;  
(no need to used columns in this solution).

barsoom

  • Jr. Member
  • **
  • Posts: 51
Re: Problems with stringgrid alignments and background color
« Reply #4 on: July 29, 2021, 01:26:28 am »
I applied both, the solution from @winni and from @wp. The first one already worked to solve the issue about centering the text:
Code: Pascal  [Select][+][-]
  1. procedure TForm6.SunGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  2.   aRect: TRect; aState: TGridDrawState);
  3. var
  4.   s:  string;
  5.   dx: integer;
  6. begin
  7.   if (ACol = 3) and (ARow >= 1) then
  8.     with TStringGrid(Sender) do
  9.     begin
  10.       if aState * [gdSelected, gdFocused] <> [gdSelected, gdFocused] then
  11.         Canvas.Brush.Color := $7FFFD4;
  12.       Canvas.FillRect(aRect);
  13.       s := Cells[ACol, ARow];
  14.       dx := (aRect.Right - aRect.Left - Canvas.TextWidth(s)) div 2;
  15.       Canvas.TextOut(aRect.Left+dx,aRect.Top+2,s);
  16.       Canvas.Font.Color := clBlack;
  17.     end
  18.   else if (ACol = 4) and (ARow >= 1) then
  19.     with TStringGrid(Sender) do
  20.     begin
  21.       if aState * [gdSelected, gdFocused] <> [gdSelected, gdFocused] then
  22.         Canvas.Brush.Color := clSkyBlue;
  23.       Canvas.FillRect(aRect);
  24.       s := Cells[ACol, ARow];
  25.       dx := (aRect.Right - aRect.Left - Canvas.TextWidth(s)) div 2;
  26.       Canvas.TextOut(aRect.Left+dx,aRect.Top+2,s);
  27.       Canvas.Font.Color := clBlack;
  28.     end;
  29. end;
However, the solution of @wp using "onPrepareCanvas" didn´t produce changes about to center the string of each cell, in spite i corrected the TextRect instead TextOut. In any case, it worked to change the color of the cell if is is selected. The problem is that it only changes the font color when selected, not the cell color, except if the specific cell is selected.


paweld

  • Hero Member
  • *****
  • Posts: 966
Re: Problems with stringgrid alignments and background color
« Reply #5 on: July 29, 2021, 07:56:09 am »
onPrepareCanvas, without onDrawCell
Best regards / Pozdrawiam
paweld

barsoom

  • Jr. Member
  • **
  • Posts: 51
Re: Problems with stringgrid alignments and background color
« Reply #6 on: July 29, 2021, 08:07:33 pm »
Thanks @paweld....
Quote
onPrepareCanvas, without onDrawCell
It was my fault.... i was using both and probably overlapped resulting in a behaviour i didn´t want.

Thanks so much for the example, and thanks to all of you for your quick and illustrative answers!

SOLVED!!
« Last Edit: July 29, 2021, 08:10:38 pm by barsoom »

 

TinyPortal © 2005-2018