I want to draw on the canvas of a cell in a string grid. This is going to be on top of an image preloaded into the string grid.
Currently instead of drawing on top of the image, I am loading a second transparent image and then painting on top of the cell. This is the code I use and it works.
procedure TfrmCavern.StringGridDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
index : integer;
I : integer;
begin
// Calculate the corresponding linear index
index := LinearIndexOf(ARow, ACol);
//Draw image referenced to cell
StringGrid.Canvas.StretchDraw(Rect, CellDetails[index].Images.Picture.Graphic);
//if player present draw corresponding player image
for I := 0 to frmWelcome.NoofPlayers - 1 do
begin
if index = Players[I].pIndex then StringGrid.Canvas.StretchDraw(Rect,Players[I].UserImage.Picture.Graphic);
end;
end;
end;
The procedure first draws the image referenced to the cell. If there is a "player" present it will then draw the player piece on top. Because the "player piece" image is a transparent .PNG image the original image underneath is still visible.
The draw back of this method is that the "player piece" is in a set position within the cell due to the image being constant. I want to be able to draw the "player piece" in a different position within the cell depending on which cell is selected. I have around 200 cells so I dont really want to manually create that many images with different positions.
I've tried drawing directly to the canvas of the stringgrid within the drawcell procedure but that appeared to reference the entire stringgrid rather than the current cell that was being drawn.
StringGrid.Canvas.ellipse(10,10,50,50);
I've looked but I cant seem to be able to reference the canvas of the current cell - I presume it doesn't exist?
The next thing I tried was drawing to a temporary image and then drawing the image to the cell.
TempImage.Canvas.Ellipse(10,10,50,50);
StringGrid.Canvas.StretchDraw(Rect, TempImage.Picture.Graphic);
This worked to an extent, it did draw the image to the cell, however the image had an opaque background/canvas so the cell was white with the circle on it, the image beneath was not visible. I did a bit of research but couldn't find a way to make the canvas of the image transparent.
The last thing I can think of trying is to write an algorithm to locate the top left point of the current cell and then draw direct to the canvas from there, but that could be sloggy and create issues when redrawing the stringgrid.
Can anyone see a way around my issue?
Thanks in advance, Josh
There is only one canvas, the control's canvas. Each cell is merely a rectangle inside this canvas. It is trivial to find the position of the current cell in the canvas. Indeed, this is what the Rect
parameter is for. Rect.Left
is the x coordinate of the cell, and Rect.Top
is the y coordinate of the cell.
Or did I misinterpret your question?
The Rect
parameter to OnDrawCell specifies the bounds of the particular cell, relative to the grid's client coordinate system. So you need to draw to coordinates that lie within this rectangle. Try something like this in your event handler:
StringGrid.Canvas.Pen.Color := clBlack;
StringGrid.Canvas.Brush.Style := bsClear;
StringGrid.Canvas.Ellipse(
Rect.Left+5,
Rect.Top+5,
Rect.Left+15,
Rect.Top+15
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With