Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I make a TMemo size itself to the text it contains? - Firemonkey

I found that this question has been asked before for VCL, but I haven't had any luck getting the answers for that question to work on a Firemonkey TMemo.

I've noticed that memo.Lines.Count always seems to match the line count based off how many I add, not as they're formatted (the memo does have wordwrap turned on). Without knowing that number I'm not sure how to start figuring this out.

Any ideas?

Edit: The width of the memo will depend on the orientation of the device, obviously if the width changes the number of lines showing could change. Also, I'd like to not alter the font of the memo.

like image 205
Sentient Avatar asked Feb 14 '23 18:02

Sentient


2 Answers

Procedure ResizeMemo(AMemo: TMemo);
const
  Offset = 4; //The diference between ContentBounds and ContentLayout
begin
  AMemo.Height := AMemo.ContentBounds.Height + Offset;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ResizeMemo(Memo1);
end;
like image 139
Agustin Seifert Avatar answered Apr 09 '23 23:04

Agustin Seifert


The following function should give you what you want. It does not change anything in the memo and takes into account the font and any line breaks and wraps. If setting the memo height to the calculated value, you will need to add a few pixels for borders to eliminate scrollbars.

(add fmx.text to uses statement for XE3, might be different for other versions as they keep changing things with each release)

function get_memo_height(amemo:tmemo):single;

var i:integer;
    astring:string;
    layout:ttextlayout;

begin
  Layout := TTextLayoutManager.DefaultTextLayout.Create;
  astring:='';
  for i:=0 to amemo.lines.count-1 do astring:=astring+amemo.lines[i]+chr(10);
  Layout.BeginUpdate;
  Layout.Text :=astring;
  Layout.WordWrap := amemo.wordwrap;
  Layout.HorizontalAlign := amemo.TextAlign;
  Layout.MaxSize := PointF(amemo.width-amemo.VScrollBar.width,maxint);
  Layout.VerticalAlign := tTextAlign.taLeading;
  Layout.Font := amemo.Font;
  Layout.TopLeft := pointf(0,0);
  Layout.EndUpdate;
  result:=layout.textrect.bottom;
  Layout.free;
end;
like image 27
David Peters Avatar answered Apr 10 '23 00:04

David Peters