Recent

Author Topic: TDrawGrid pickup  (Read 1566 times)

polpero

  • Full Member
  • ***
  • Posts: 127
TDrawGrid pickup
« on: May 13, 2024, 05:31:07 pm »
Hi

Suppose a TDrawGrid named dGrid of 5 cells in a row,
each colored differently using the following array of colors;

Code: Pascal  [Select][+][-]
  1. const defPal: array[0..4] of TColor =
  2.        (clBlack,clGray,clMaroon,clOlive,clGreen);

and a TShape called PickedColor.

On the grid the colors are assigned on DrawCell event

Code: Pascal  [Select][+][-]
  1. procedure TdGridFrm.dGridDrawCell(Sender: TObject; aCol, aRow: Integer;
  2.   aRect: TRect; aState: TGridDrawState);
  3. begin
  4.   with dGrid do
  5.    begin
  6.      canvas.brush.color := defPal[aCol] ;
  7.      canvas.FillRect(CellRect(ACol, ARow));
  8.     end;
  9. end;

How can i 'pick' (on MouseDown) the color from a dGrid.cell to assign it to PickedColor.brush
without referring to the color Array? Without doing:

Code: Pascal  [Select][+][-]
  1. procedure TdGridFrm.dGridMouseDown(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var C,R: longInt;
  4. begin
  5.   dGrid.MouseToCell(X, Y, C, R);
  6.   PickedColor.brush.color :=  defPal[C];
  7. end;  


It seems that each cellRect don't have a specific canvas... 
So is there a unique canvas for the entire grid?
Must we clip a rectangle from that canvas?

I have not found much examples using the drawGrid around.

Thanks

wp

  • Hero Member
  • *****
  • Posts: 12872
Re: TDrawGrid pickup
« Reply #1 on: May 13, 2024, 06:23:38 pm »
How can i 'pick' (on MouseDown) the color from a dGrid.cell to assign it to PickedColor.brush
without referring to the color Array? Without doing:

Code: Pascal  [Select][+][-]
  1. procedure TdGridFrm.dGridMouseDown(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var C,R: longInt;
  4. begin
  5.   dGrid.MouseToCell(X, Y, C, R);
  6.   PickedColor.brush.color :=  defPal[C];
  7. end;  
This is not possible because the DrawGrid does not store any data. And if you think that assignment of a color to the brush in the OnDrawCell woud be persistent: no, there a common canvas for the entire grid, and the brush.color (like many other canvas properties) is making many changes while the entire grid is drawn. And even the canvas itself is not persistent, it safely exists only during the paint operation. This means that if you draw to the canvas outside the OnDrawCell event the drawing will disappear when the operating systems decides to redraw the grid later (for example because you drag another window over the grid), and some operating systems even will crash the application in case of such an "illegal" drawing.

Handoko

  • Hero Member
  • *****
  • Posts: 5445
  • My goal: build my own game engine using Lazarus
Re: TDrawGrid pickup
« Reply #2 on: May 13, 2024, 06:46:16 pm »
Done.

Tested on Ubuntu Mate only:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Grids, ExtCtrls, StdCtrls;
  9.  
  10. const
  11.   ColumnCount = 4;
  12.   RowCount    = 6;
  13.  
  14. type
  15.  
  16.   { TForm1 }
  17.  
  18.   TForm1 = class(TForm)
  19.     DrawGrid1: TDrawGrid;
  20.     Label1: TLabel;
  21.     Shape1: TShape;
  22.     procedure DrawGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  23.       aRect: TRect; aState: TGridDrawState);
  24.     procedure DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  25.       Shift: TShiftState; X, Y: Integer);
  26.     procedure FormCreate(Sender: TObject);
  27.   private
  28.     FColors: array[0..ColumnCount-1, 0..RowCount-1] of LongInt;
  29.   end;
  30.  
  31. var
  32.   Form1: TForm1;
  33.  
  34. implementation
  35.  
  36. {$R *.lfm}
  37.  
  38. { TForm1 }
  39.  
  40. procedure TForm1.DrawGrid1DrawCell(Sender: TObject; aCol, aRow: Integer;
  41.   aRect: TRect; aState: TGridDrawState);
  42. begin
  43.   with DrawGrid1 do
  44.   begin
  45.     Canvas.Brush.Color := FColors[aCol, aRow];
  46.     Canvas.FillRect(CellRect(aCol, aRow));
  47.   end;
  48. end;
  49.  
  50. procedure TForm1.DrawGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  51.   Shift: TShiftState; X, Y: Integer);
  52. var
  53.   Selected: LongInt;
  54.   Col:      Integer;
  55.   Row:      Integer;
  56. begin
  57.   Col      := DrawGrid1.MouseToCell(Point(X, Y)).X;
  58.   Row      := DrawGrid1.MouseToCell(Point(X, Y)).Y;
  59.   Selected := FColors[Col, Row];
  60.   Caption  := Col.ToString + ':' + Row.ToString;
  61.   Shape1.Brush.Color := Selected;
  62. end;
  63.  
  64. procedure TForm1.FormCreate(Sender: TObject);
  65. var
  66.   i, j: Integer;
  67. begin
  68.   DrawGrid1.FixedCols := 0;
  69.   DrawGrid1.FixedRows := 0;
  70.   DrawGrid1.ColCount  := ColumnCount;
  71.   DrawGrid1.RowCount  := RowCount;
  72.   for i := 0 to ColumnCount-1 do
  73.     for j := 0 to RowCount-1 do
  74.       FColors[i, j] := Random($FFFFFF);
  75. end;
  76.  
  77. end.
« Last Edit: May 13, 2024, 06:50:32 pm by Handoko »

jamie

  • Hero Member
  • *****
  • Posts: 6964
Re: TDrawGrid pickup
« Reply #3 on: May 13, 2024, 11:16:05 pm »
I just conducted this test.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1PrepareCanvas(Sender: TObject; aCol, aRow: Integer;
  2.   aState: TGridDrawState);
  3. begin
  4.   TstringGrid(Sender).Rows[aRow].Objects[acol]:= self;
  5.   if TStringGrid(Sender).Rows[aRow].Objects[acol] = self Then Caption := 'True'
  6.   else caption := 'false';
  7. end;                                                                              

This shows that if you store an object in the TStrings that is returned, it seems to store it for later retrieval, maybe.
The only true wisdom is knowing you know nothing

polpero

  • Full Member
  • ***
  • Posts: 127
Re: TDrawGrid pickup
« Reply #4 on: May 16, 2024, 02:28:23 am »
Nice test Jamie but we are investigating TDrawGrid here... :)

jamie

  • Hero Member
  • *****
  • Posts: 6964
Re: TDrawGrid pickup
« Reply #5 on: May 16, 2024, 03:02:54 am »
Nice test Jamie but we are investigating TDrawGrid here... :)

And yes?

I guess you don't see the point of extra storage per cell.

Oh well.
The only true wisdom is knowing you know nothing

polpero

  • Full Member
  • ***
  • Posts: 127
Re: TDrawGrid pickup
« Reply #6 on: May 16, 2024, 03:11:43 am »
Sure I do
And i use it regularly
I'm just trying to understand the limits of the DrawGrid

and I do recognise the value of your test
sorry if it sounded harsh... was not meant this way


 

TinyPortal © 2005-2018