FireMonkey コントロールの配置
FireMonkey アプリケーションでは、1 つ以上のコントロールをフォーム上に表示します。フォームには、2D や 3D のコンテンツを含むことができ、混在させることもできます。
目次
FireMonkey の座標系の使用
フォーム デザイナでは、座標系の原点は左上で、そこから右下に展開します。座標は単精度浮動小数点数で表現されます。サポートされているすべてのプラットフォームで正方画素が使われます。1 つの座標単位が通常は 1 ピクセルに対応しますが、いくらかの明確な例外が存在します。
- 2D コントロールの Position プロパティは、X および Y というプロパティを持つ TPosition です。 Width および Height という別々のプロパティでサイズを表します。
- 3D オブジェクトで使用している TPosition3D には、さらに Z というプロパティがあり、正の値が画面の奥を指します(X が左、Y が下を指すため、"右手の法則" に従っていることになります)。また、Depth というプロパティもあります。この位置とサイズによって、コントロールを表す境界ボックスの 1 つであるコンテンツ ボックスが定義されます。
FireMonkey コントロールは親、子、所有者をもつ
FireMonkey では、どのコントロールでも別のコントロールの親になることができます。
通常は、フォームがそこに含まれるすべてのコントロールを所有します。フォーム デザイナで配置したコントロールは、この慣例に従います。所有者は、共通の Create コンストラクタが受け取る最初で唯一の引数です。
TFmxObject.Create(AOwner: TComponent)
コードでコンポーネントを作成するときには、今後フォームが存続している間ずっとコントロールも存続するのであれば、フォームを所有者に指定します。フォームは、Self として、または既存コントロールの Owner として、簡単に使用できるはずです。所有者は、それ自体を破棄するときに同時にコントロールも破棄する責任を負います。
一時的なコンポーネントの場合は、所有者として nil
を渡します。この場合、使い終わったときにコンポーネントを破棄するのはコードの責任です。例外が発生した場合も含めてコンポーネントが必ず破棄されるよう、try/finally ブロックを使用することをお勧めします。
所有者を設定するだけでコントロールがフォームに表示されるわけではありません。コンポーネント ツリー内で、フォームの直接の子として、またはツリーのもっと下の方に、コントロールを置く必要があります。フォーム デザイナでコントロールを配置した場合には、これは自動的に行われ、[構造]ビューにコンポーネント ツリーが表示されます。コードでコントロールを作成した場合には、Parent プロパティにフォームまたは適切な親コントロールを設定します。
子の位置は親からの相対的な位置になります。座標が 0 であれば、子と親の左上角は同じ位置になります。
コンテナのようなコントロールしか親になれないわけではありません。また、ClipChildren プロパティのデフォルト値は False です(True であればコントロールのコンテンツ ボックスの外に子を描画することはできません)。そのため、正式なコンテナがなくても、関連するコントロール群をその場その場で集合にまとめられます。たとえば、TLabel を、そのラベルに対応する TEdit の子にすることができます。ラベルの位置に負の値を設定すると、コントロールの上や前に配置できます。TEdit を移動すると両者が同時に移動します。TLayout を他の機能を持たないコンテナとして使用し、他のコントロールを配置することができます。
座標空間のほかに、子オブジェクトは可視性、透過度、回転角度、縮尺などの属性を共有します。親のこういった属性を変更すると、サブツリーに含まれるすべての子に影響が及びます。
マージンとパディングを使った整列
コントロールの Align プロパティによって、初期表示の際および親がサイズ変更された際に、親の 4 辺または中心に合わせて自動的に位置やサイズが一緒に変更されるかどうかが決まります。デフォルト値は None で、自動計算は行われず、コントロールの位置は元のままになります。このプロパティは TAlignLayout 型の列挙値で、他に十数種類の値を取ることができます。その多くでは、2 つの値を使って自動整列の計算が行われます。2 つとは、親の Padding とコントロールの Margins です。
Padding を指定すると、親のコンテンツ ボックスの内側に空間が確保されます。たとえば、親の上と左のパディング値が両方とも 10 であれば、左上に自動配置されるコンポーネントの位置は 10,10 に設定されます。
より正確に言うと、自動配置されるのはコントロールのコンテンツ ボックスではなく、レイアウト ボックスです。この 2 つの違いはコントロールの Margins です。Margins を指定すると、コントロールのコンテンツ ボックスの外側に空間が確保されます。マージンのサイズが大きくなっても、レイアウト ボックスのサイズは元のままで、制約がある場合にはコンテンツ ボックスのサイズが小さくなります。たとえば 10,10 の例では、上と左のマージンが両方とも 5 であれば、コントロールの位置は 15,15 になります。
メモ: FireMonkey におけるマージンとパディングの役割は、CSS のボックス モデルに準じます。
Margins を指定すると、親によって自動配置されるコントロールの間を離すことができ、Padding を指定すると、それらのコントロールと親の辺の間を離すことができます。これは、マージンやパディングに正の値を指定した場合に当てはまり、負の値も指定可能です。マージンに負の値を指定すると、子は親のコンテンツ ボックスの外に配置され、ClipChildren プロパティが False なら外であっても描画されます。パディングに負の値を指定すると、コントロールのコンテンツ ボックスは計算されたレイアウト ボックスの外に配置されます。
アンカーの使用
コントロールがその親の端から特定の距離に位置を保たなければならない場合や、自分の端と親の端との距離を当初の値に保ちながら拡大しなければならない場合に、アンカーが必要になります。アンカー設定されたコントロールは、コンテナの辺に固定され、指定された場合は伸び縮みします。アンカーの組み合わせとネストしたコンテナを使用すると、インテリジェントで伸縮可能なレイアウトを FireMonkey で作成できます。コントロールのアンカーを設定するには、Anchors プロパティを使用します。アンカー設定されたコントロールでは、実行時に親のサイズが変更されても、設計時に指定した、自分と親の端との距離が一定に保たれます。設計時には、Anchors プロパティを設定しても、フォームに対する視覚効果はありません。
コントロールのアンカーを設定できるのはゼロ個以上の辺です。向かい合った辺に同時にコントロールのアンカーを設定する場合(Anchors=[akLeft, akRight] または Anchors=[akTop,akBottom])、コントロールは横または縦に伸び縮みして、親コントロールの左右または上下の辺への距離を一定に保ちます。コントロールは親の 4 辺すべてにアンカーを設定できます。この場合は、すべての方向に伸び縮みします。デフォルトでは、コントロールは自分のコンテナの上辺および左辺にアンカーで固定されます(Anchors=[akTop,akleft])。
Align を使用すると、Anchors は影響を受けます。 自動整列で設定されるアンカーは除きます。
メモ: スクロール レイアウト(TScrollBox、TVertScrollBox など)の子を右端や下端に固定しないでください。スクロール レイアウトの子の Anchors プロパティを akBottom、akRight、またはその両方に設定すると、レイアウトの内容のサイズを計算している間、レイアウトの端からの距離を一定に保とうとして、子は広がり続けることになります。スクロール レイアウトの子は、左端および上端にのみ固定してください。
拡大縮小と回転
その他に、コントロールが最終的に描画される位置に影響する一般的な属性が 2 つあります。拡大縮小と回転です。
メモ: 拡大縮小や回転を指定しても、コントロールの位置やサイズのプロパティが変わるわけではありません。反映されるのはフォーム デザイナです。オブジェクトを選択すると表示される 8 つのグリップの点(角に 4 つと辺に 4 つ)が実際のコンテンツ ボックスを示します。これは拡大縮小や回転が行われる前の、手動で設定されるかレイアウトを元に計算されたものです。
コントロールの Scale プロパティは、Position と同じ型(2D オブジェクトなら TPosition、3D オブジェクトなら TPosition3D)のインスタンスで表されます。 X、Y、Z のデフォルト値は 1 で、オブジェクトがどの方向にも拡大縮小されていないことを意味します。 Scale の値はそれぞれの軸に対して単純に掛けられます。 値が 1 より大きければ、軸に沿って拡大します。 値が 0 より大きく 1 より小さければ、軸に沿って縮小されます。 Scale のどれかの軸が 0 であれば、コントロールは表示されなくなります。 一定の比率で拡大縮小するには、すべての軸に同じ値を指定する必要があります。
2D の拡大縮小は、常にコントロールの原点、つまりコンテンツ ボックスの左上を固定して行われます。負の値が指定された場合には、その原点の逆側に表示されます。たとえば Scale の X が負の値であれば、コントロールは、コンテンツ ボックスの左の辺で反転して左下に描画されます。3D の拡大縮小はオブジェクトの中心を起点に行われます。
2D の回転では、中心点を変更できます。RotationCenter プロパティも TPosition ですが、値は単位座標です。0,0 はコントロールの左上、1,1 は右下です。デフォルトはコントロールの中心を示す 0.5,0.5 です。コンテンツ ボックスの縦横比は関係しません。RotationAngle は、その点を中心とした時計回りの角度です。
3D での回転は常に中心から行われ、TPosition3D 型の RotationAngle で X 軸、Y 軸、Z 軸の角度を示します。回転も右手の法則に従って行われます。たとえば X と Y の回転が 0 で、Z 軸が画面の奥を指し、Z 軸の回転が正であれば時計回りに回転します。
2D では、拡大縮小をしてから回転を行います。拡大縮小は原点から行い、回転の中心は変更可能なため、この順序は重要です。3D の場合はどちらも中心から行われるため、順序は問題ではありません。
FireMonkey レイアウトの使用
FireMonkey レイアウトは、他のコントロールをグループ化し、全体として配置および操作できるようにするためのコンテナです。 FireMonkey レイアウトは非ビジュアル コンポーネントです。 layoutsを上記の 1 つ以上の配置方法と一緒に使用すると、複雑な数値計算を使用せずに複雑なインターフェイスができあがります。
子コントロールの配置があらかじめ定義されているレイアウトがあります。
- TFlowLayout は、段落内の単語と同じように子コントロールを整列させます。
- TGridLayout では、各セルのサイズが等しいグリッド内に子コントロールが配置されます。コントロールはすべて、セルに合わせて自動的にサイズ変更されます。この種のレイアウトを使用する場合、コントロールの整列、位置、およびアンカーのプロパティは自動的に設定されます。これらのプロパティを明示的に変更しても無視されます。TGridLayout を使用する場合は、コントロールのサイズが影響を受け自動的に設定されます。
- TGridPanelLayout では、子コントロールがグリッド パネルに配置されます。各コントロールはグリッドのセル内に置かれますが、セル内でコントロールのサイズを手動で変更することが可能です。コントロールが複数のセルにまたがるよう指定することができます。
FireMonkey では、子コントロールを含むスクロール領域を表すスクロール ボックス レイアウトもいくつか用意されています。
以下のスクロール ボックスを使って、複数のコントロール(ボタン、リスト ボックス、編集ボックス、ラジオ ボタンなど)を、スクロール可能な同じ親の下にグループ化することができます。
- TScrollBox -- フォーム内のスクロール領域を表します。
- THorzScrollBox -- 水平スクロールに限定した TScrollBox を表します。
- TVertScrollBox -- 垂直スクロールに限定した TScrollBox を表します。
- TFramedScrollBox -- 周りを囲むフレームを持ち、背景が不透明である TScrollBox を表します。
- TFramedVertScrollBox -- 周りを囲むフレームを持ち、背景が不透明である TVertScrollBox を表します。
スクロール ボックスを使用すると、コントロールをスクロール可能な領域にまとめてフォーム上であまり場所を取らないようにできるため、多数のコントロールをフォームに含めることができます。 その他に、スクロール ボックスを使って、フォーム内の複数の領域(ビュー)をスクロールさせることができます。 ビューは、市販のワード プロセッサや、スプレッドシート、プロジェクト管理アプリケーションなどで一般的に使われています。
iOS、Mac OS、Android では、スクロール ビューがジェスチャの速度と方向に反応して、ユーザーから見て自然な感じにコンテンツが表示されます。FireMonkey には、スクロール ビューのそのようなスムーズな慣性スクロールを Windows 上でまねるための InertialMovement ユニットが用意されています。
アクセラレータ キーを使用する
アクセラレータ キーを、FireMonkey コントロールやアクションに対して定義するには、アクションのコントロールの Text プロパティを使用します。 アクセラレータ キーがサポートする FireMonkey コントロールおよびアクションは: