Drawing different icons in a cell

I am looking for a way to draw different icons in a cell, depending on the GridDrawState.
At the moment I draw the icons by using the GetDisplText event:

procedure TForm1.GridGetDisplText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  if Value = '$$' then
  begin
    Value := '<IMG src="arrowup">';
  end;
end;

This works, but when the row is selected the icon is not visible very well, because it's dark and the color of the row is dark too. I would like to draw a white version of that icon, just like the text is light, but I don't know the GridDrawState at this moment.
The GridDrawState is supplied in the GetCellColor event, but then I can't supply the icon.
What to do?

Anybody? Maybe there is a different way to draw icons in a grid, so I can draw a white one when a row is selected and a black one when it is not?

Good morning Ronald,

even if i do not work with cell images i sugggest to read page 66 of advstring manual.

The chapter is "TAdvStringGrid cell graphics" and cover what you are loking for, ech cells have it's own pictures.

Hope you can solve your problem



Regard

Daniele

Hello Daniele,

I have read the manual, but the techniques described there do not solve my problem. I tried one that uses an imagelist, but that gives me the same problem.
I will describe the problem in a bit more detail, maybe that will clear it up.

1. I draw an image in a cell that represents the status of that row. Let's say a green circle. The circle is clearly visible, because the background is white.
2. I select that same row. The circle does not change and so now I see a green circle on a dark blue background (the selection color is blue). The circle now is almost not visible.
3. I also have an image with a white circle. That one is very well visible on a blue background, so I am looking for a way to draw that white circle INSTEAD of the green circle when the row is selected.

I hope that clears things up.

Hi Ronald,

as i sad before i neer work with graphics into a cell .... but in order to understand better the problem i made a very simple test.



New form only 1 TAdvStringGrid.

here the formcreate some events



procedure TForm2.FormCreate(Sender: TObject);

Var I : Integer;

begin

SG1.Clear;

SG1.RowCount:=6;

SG1.ColCount:=3;

SG1.Cells[1,0]:='Test 1';

SG1.cells[2,0]:='Test 2';

for I:=1 To SG1.LastRow do

      SG1.CreateBitmap(1,I,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Application exit 48 x 48.bmp');

SG1.AutoSizeColumns(True);

SG1.AutoSizeRows(True);

end;



procedure TForm2.SG1CellValidate(Sender: TObject; ACol, ARow: Integer;

var Value: string; var Valid: Boolean);

begin

if Value<>'' then

Begin

    SG1.CreateBitmap(1,ARow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Bulb 48 x 48.bmp')

End

Else

SG1.CreateBitmap(1,ARow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Application exit 48 x 48.bmp');

end;



procedure TForm2.SG1RowChanging(Sender: TObject; OldRow, NewRow: Integer;

var Allow: Boolean);

begin

if SG1.Cells[1,Oldrow]='' then SG1.CreateBitmap(1,OldRow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Application exit 48 x 48.bmp')

Else

SG1.CreateBitmap(1,OldRow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Bulb 48 x 48.bmp');

if SG1.Cells[1,Newrow]='' then SG1.CreateBitmap(1,NewRow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\bank 48 x 48.bmp')

else

SG1.CreateBitmap(1,NewRow,True,haBeforeText,vaTop).LoadFromFile('C:\Immagini\Bulb 48 x 48.bmp')

end;



With this simple example i fill the grid with few rows, for each row in column 1 i set a bitmap (this is only an example, i got the first 3 image !!!).

After that rearrange the row and column size.

As you can see, when you change the column you chage the picture too; the same if you insert some text.

Of course, this is only an example and there is some more work to do (as cell width resize according to the text and so on ...) but this can be a good starting point (remeber to load you own pictures.



If i understand well the code, the createbitmap procedure automatically free the old picture.



So, in your project

1 According to the cell status load the rigth pictures

2 handle the picture according to your rules



and with



procedure TForm2.SG1GetCellColor(Sender: TObject; ARow, ACol: Integer;

AState: TGridDrawState; ABrush: TBrush; AFont: TFont);

begin

if (Arow>0) and(Acol>0) then

Begin

    if SG1.Cells[Acol,arow]<>'' then Abrush.Color:=clRed

    Else

    Abrush.Color:=clWhite;

End;

end;



you can control the cells background color too.



Have a nice day



Daniele

Hi, I appriciate your effort, but I don't get the right result this way, although I am getting a bit closer now.
I use icons to display various states in the program instead of text. That means the text will not be displayed, only the icons. So if I add something to your program in the FormCreate:

  SG1.cells[1,1]:='Hello';

I obviously get the Text 'Hello' in that cell along with the icon. But I don't want to display the text, so I add this function:

procedure TForm1.SG1GetDisplText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  if ACol = 1 then Value := '';
end;

I which case the text is gone, but the SG1CellValidate function does not work anymore.

Hi Ronald,

the code is just a starting point.

To be honest i do not see a real problem.

Your need is change a picture into a cell grid accarding your rules, without any text.

In order to avoid text typing, just set the option goEditing to false.

In order to change the picture (or icon) in the cell grid, you must work with SG1.CreateBitmap only.

With this example you can change the picture when you change row or, wait the picrture changing in timer event.

And this is very close (if not is the your case solution) to what you are searching.

Better ... i modified the example and put 1 edit where you intend change the picture.

In your project, instead the edit, consider your logic in order to change the image.



https://files.fm/u/z9chzx8d



In the same way, i used bmp files .... you use your ico, jpg ecc... files



Hope you can solve the matter



Regard

Daniele

I am still not getting the result I want. I am really close and I want to use HTML-formatting.
I will rephrase my question, maybe that will solve it:

I fill virtual cells in the grid with a GetDisplText event. This event is only triggered when necessary, e.g. when something has to be redrawn.
Can I trigger this event myself after I have changed something in a cell?

Hi Ronald,

to be honest ... for this matter you do not have a real problem.

This because you can handle the image in any way you need.

You populate the grid with your images and, according to your rules, you need to change the pictures.

For example you fill the grid with image1, now happend something and in col 3 row 5 you pass the text 'change'; Now you have Cell[3,5]='change'.

Now with procedure GetDisplText(Sender: TObject; ACol, ARow: Integer; var Value: string)

you can check and change the text as your need, for example

procedure TForm1.SG1GetDisplText(Sender: TObject; ACol, ARow: Integer;

var Value: string);

begin

    If Value = 'change' then Value = '<IMG src="file://C:\Immagini\Bulb 48 x 48.bmp">';

end;

In this case, everytime you pass 'change' in any cells, you get the that image .

Also if you are writing in a cell, when you press enter key first is fired up the validate event, after the getdisplaytext.

You can avoid the getdisplay text working into oncellvalidate.

Hope you can reach the solution

Regard

Daniele

Thanks for your effort, but that is not what I am looking for. I tried to discribe it in my last post.
The main problem is that the GetDisplText event is not triggered when the value in an underlying field is not changed. I have the code below, but it is not always triggered:

procedure TFormRitten.CGGetDisplText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  if (Value = 'PIC') then
  begin
    if CG.IsNode(ARow) and CG.GetNodeState(Arow) then
    begin
      Value := '<IMG src="toon alle ritregels_104">';
    end
    else
    begin
      if CG.RowSelect[ARow] then
      begin
        Value := '<IMG src="pijl omhoog_101">'';
      end
      else
      begin
        Value := '<IMG src="pijl omhoog_108">'';
      end;
    end;
  end;
end;



Hi Ronald,

did you try to change event ??

AdvGrid has this event GetCellColor; The main purpuse of this event is hanlde the background cell's color and it's:

GetCellColor(Sender: TObject; ARow, ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);

This event is called thousand time and you can insert your logic here.

So you try to change your code into



procedure TFormRitten.CGGetCellColor(Sender: TObject; ARow, ACol: Integer;

AState: TGridDrawState; ABrush: TBrush; AFont: TFont);

begin

if (CG.Cells[Acol,Arow] = 'PIC') then

begin

    if CG.IsNode(ARow) and CG.GetNodeState(Arow) then

    begin

      CG.Cells[Acol,Arow] := '<IMG src="toon alle ritregels_104">';

    end

    else

    begin

      if CG.RowSelect[ARow] then

      begin

        CG.Cells[Acol,Arow] := '<IMG src="pijl omhoog_101">'';

      end

      else

      begin

        CG.Cells[Acol,Arow] := '<IMG src="pijl omhoog_108">'';

      end;

    end;

end;

end;



Little dirty ... but work...

Hope this is the good time !!!



Regard

Daniele

Good idea, I use that event as well to color some of my lines, but it won't work, because I do NOT want to change the values in the cells, I want to display something else on the fly, hence the GetDisplText event.
I guess it won't be possible to do what I want...

Hi Ronald,

when the value is "PIC" you display a image.

In this moment you change the cell value !!

Have you a mini project where is possible see what is your need and what is not working?



Daniele

I will look into it.