FMXのTGridLayout
こんにちは、この記事はDelphi Advent Calendar 2023 7日目の記事です。
皆さん、TGridLayoutは使われていますでしょうか。
横方向か縦方向に同じサイズでコンポーネントを配置してくれるLayoutです。
コンポーネントの並び順はOrientationプロパティ、コンポーネントのサイズはItemWidth, ItemHeightプロパティでで指定します。
で、この Item##### プロパティですが、OrientationがHorizontal(横並び)の場合はItemWidthに、Vertical(縦並び)の場合はIteHeightに負の値を設定すると、コンポーネントの数に合わせて自動でサイズ調整してくれます。(Helpには載っていません...)
が、しかし、サイズ調整する時にHeightやWidthをコンポーネント数で割って、その値をコンポーネントに設定するのですが、そのサイズはSingleです。
勘のいい方ならもうお気づきでしょうが、まれにサイズ調整がうまくいかずに意図せず次の行や列にコンポーネントが配置されてしまう事象が発生します。
これを回避するためにTGridLayoutのDoRealignプロシージャを書き換える必要が有ります。
簡単にはTGridLayoutを使用するUnitに
TGridLayout = class(FMX.Layout.TGridLayout)
procedure DoRealign; override;
end;
として、FMX.LayoutsからDoRealignを丸ごとImplimentationの実装部にコピーします。
実装部でFItemWidthとFItemHeightがPrivateで宣言されているのでアクセスできませんので、
Fを取ってItemWidth, ItemHeightとします。
CurPos.X := Self.Padding.Left;
CurPos.Y := CurPos.Y + LItemHeight;
と
CurPos.Y := Self.Padding.Top;
CurPos.X := CurPos.X + LItemWidth;
の部分を
if( 0 <= ItemWidth )then
begin
curPos.X := Self.Padding.Left;
curPos.Y := curPos.Y + iHeight;
end;
や
if( 0 <= ItemHeight )then
begin
curPos.Y := Self.Padding.Top;
curPos.X := curPos.X + iWidth;
end;
のように改行、改列部分にItemWidthやItemHeightが負の値かどうかの判定を入れることにより思惑通りの動作になります。
以上であります。3maでした。