Remark

Hi,

There is a small error in the creation of icons (for the library) when using the 'simple' program. When adding a textblock and pressing the 'add to library' only the blocks are correctly resized. Not the text.
As I tweaked this a bit for an implementation I got, I solved the issue by doing a recalculation of the fonts height based on the total height of the textblock. Important is to first resize the groupblock by setting the boundsrect. Otherwise the boundsrect of the textblock is still the old one (not resized).
This error occurs as well when resizing a block in design time. The block is smaller, but the text remains the same. In my implementation, based on the size of the boundsrect, the height of the font will be smaller as well.

Anyway, so everyone knows what a possible solution is...
Geert

Hi Geert,

 
can you point out the changes you made in code? I'm not sure if I understood what you mean resizing a block in design time, since icons for the library are only used in runtime?
 
You can send us a private e-mail to our support e-mail, if you prefer.

No worries, here's the complete function


I added a function 'Calc_Height_text' which will reduce the textblock font height based on the icon, created at 24 pxls

Just make a textblock in the 'simple' demo without underneeth adaptation. You will see that the text in the textblock doesn't shrink.

Hope this helps
Geert


function TfmLibItemEditor.DrawIconFromBlock(AItem: TDgrLibraryItem): boolean;
const
  ICONSIZE = 24;
var
  dgr: TatDiagram;
  str: TStringStream;
  i,j: integer;

  function FitBlockRect(AWidth, AHeight: number): TSquare;
  var
    x, y, x1, y1: double;
  begin
    if AWidth > AHeight then
    begin
      y := ICONSIZE / AWidth * AHeight;
      x := ICONSIZE;
    end
    else
    begin
      x := ICONSIZE / AHeight * AWidth;
      y := ICONSIZE;
    end;
    x1 := ICONSIZE / 2 - x / 2;
    y1 := ICONSIZE / 2 - y / 2;
    result := Square(x1, y1, x1 + x, y1 + y);
  end;

  procedure Calc_Height_text(ADControl:TTextBlock);
  var curLineStrLst:TStringList;
  begin
    curLineStrLst := TStringList.create;
    curLineStrLst.strictdelimiter := true;
    curLineStrLst.delimiter := char(13);
    ADControl.WordWrap := false;
    curLineStrLst.DelimitedText := ADControl.TextCells.Items[0].Text;
    //In case the currentlist count is zero...
    if curLineStrLst.Count > 0 then
      TTextBlock(ADControl).TextCells.Items[0].font.Height := - Variant(ADControl.Height / curLineStrLst.Count);
    FreeAndNil(CurLineStrLst);
  end;

begin
  result := False;
  if AItem.Data > '' then
  begin
    dgr := TatDiagram.Create(Self);
    str := TStringStream.Create(AItem.Data);
    try
      dgr.Visible := False;
      dgr.Parent := Self;
      dgr.LoadFromStream(str, True);
      dgr.SetBounds(0, 0, ICONSIZE, ICONSIZE);
      for i:=dgr.DControlCount-1 downto 0 do
      begin
        //gse added for groupblocks
        if dgr.DControls is TGroupBlock then
        begin
           TGroupBlock(dgr.DControls).BoundsRect := Square(0, 0, ICONSIZE, ICONSIZE);
           for j := 0 to TGroupblock(dgr.DControls).members.Count - 1 do
           begin
              if TGroupBlock(dgr.DControls).Members.Items[j].DControl is TTextBlock then
              begin
                Calc_Height_text(TTextBlock(TGroupBlock(dgr.DControls).Members.Items[j].DControl));
              end;
           end;
        end
        else if dgr.DControls is TTextBlock then
        begin
           Calc_Height_text(TTextBlock(dgr.DControls));
        end;
        //end gse
        if dgr.DControls is TCustomDiagramBlock then
        begin
          with TCustomDiagramBlock(dgr.DControls) do
          begin
            if (Width > 0) and (Height > 0) then
              BoundsRect := FitBlockRect(Width, Height);
            if (dgr.DControls) is TTextBlock then
               Calc_Height_text(TTextBlock(dgr.DControls));
          end;
          dgr.PaintToBitmap(imIcon.Picture.Bitmap);
          imIcon.Picture.Bitmap.Width := ICONSIZE+1;
          imIcon.Picture.Bitmap.Height := ICONSIZE+1;
          result := True;
          break;
        end;
      end;
    finally
      dgr.Free;
      str.Free;
    end;
  end;
end;

Oh and I ment of course at runtime. :-)

Geert

Final remark. I used the calc_height_text as well with the onresize event of the atdiagram. If a boundsrect reduces by a user, the text will reduce automatically with this function as well to fit in the boundsrect. I'm only using the items[0] of the textcells. So its limited for my needs.

Geert

Hi Geert,

 
thanks for the code, now I understand what you mean. Unfortunately we can't add this because you are relying that the text height is the same as control height, which is not always true. Nevertheless, I think that just for the icon, text is not that important, so I changed the code to just remove any text in the block when building the icon. This way the picture will be also nice.
 
Thanks for your feedback, the fix will be included in next version.

Ah yes, see your point. In my solution, the text height will always be the height of the control (as I move the height as far as the height of the control). But true, you can't do this in a general approach.

However, there is another one that will give a problem with the icon. That's normal lines inside a diagramblock. Same thing as the text.
Hope this helps
Geert

You mean text in lines? Then yes, your approach won't work on that either. Next version will just remove any text in the blocks before making the icon. If you mean there is a problem with lines, then I don't see it. I can group blocks and lines here, add it to library and the icon is fine.