Einzelnen Beitrag anzeigen

Schokohase
(Gast)

n/a Beiträge
 
#9

AW: TAlignLayout.Top die Reihenfolge stimmt nicht

  Alt 5. Aug 2019, 10:17
Also für die VCL hätte ich so etwas
Delphi-Quellcode:
unit AlignChildren.Vcl;

interface

uses
  System.Types,
  Vcl.Controls;

type
  WinControlHelper = class helper for TWinControl
  public
    procedure AlignChildren(ARecursive: Boolean = false);
  end;

implementation

{ WinControlHelper }

procedure WinControlHelper.AlignChildren(ARecursive: Boolean);
var
  remainingArea: TRect;
  childControlIndex: Integer;
  currentControl: TControl;

  newTop, newLeft: Integer;
  reduce: Integer;
begin
  remainingArea := Self.ClientRect;
  remainingArea.Inflate(-Padding.Left, -Padding.Top, -Padding.Right, -Padding.Bottom);

  for childControlIndex := 0 to Self.ControlCount - 1 do
  begin
    currentControl := Self.Controls[childControlIndex];

    if not currentControl.Visible then
      Continue;

    newLeft := currentControl.Left;
    newTop := currentControl.Top;

    case currentControl.Align of
      alTop:
        begin
          newTop := remainingArea.Top;
          if currentControl.AlignWithMargins then
            Inc(newTop, -currentControl.Margins.Top);

          reduce := currentControl.Height;
          if currentControl.AlignWithMargins then
            Inc(reduce, currentControl.Margins.Top + currentControl.Margins.Bottom);

          remainingArea.Inflate(0, -reduce, 0, 0);
        end;
      alBottom:
        begin
          newTop := remainingArea.Bottom - currentControl.Height;
          if currentControl.AlignWithMargins then
            Inc(newTop, -currentControl.Margins.Bottom);

          reduce := currentControl.Height;
          if currentControl.AlignWithMargins then
            Inc(reduce, currentControl.Margins.Top + currentControl.Margins.Bottom);

          remainingArea.Inflate(0, 0, 0, -reduce);
        end;
      alLeft:
        begin
          newLeft := remainingArea.Left;
          if currentControl.AlignWithMargins then
            Inc(newLeft, -currentControl.Margins.Left);

          reduce := currentControl.Width;
          if currentControl.AlignWithMargins then
            Inc(reduce, currentControl.Margins.Left + currentControl.Margins.Right);

          remainingArea.Inflate(-reduce, 0, 0, 0);
        end;
      alRight:
        begin
          newLeft := remainingArea.Right - currentControl.Width;
          if currentControl.AlignWithMargins then
            Inc(newLeft, -currentControl.Margins.Right);

          reduce := currentControl.Width;
          if currentControl.AlignWithMargins then
            Inc(reduce, currentControl.Margins.Left + currentControl.Margins.Right);

          remainingArea.Inflate(0, 0, -reduce, 0);
        end;
    end;

    currentControl.Left := newLeft;
    currentControl.Top := newTop;

    if ARecursive and (currentControl is TWinControl) then
      TWinControl(currentControl).AlignChildren(ARecursive);
  end;
end;

end.
Das müsste für FMX ähnlich funktionieren. Dort gibt es allerdings mehr Alignment-Arten die man berücksichtigen muss. Das Prinzip ist aber gleich.

Geändert von Schokohase ( 5. Aug 2019 um 10:32 Uhr)
  Mit Zitat antworten Zitat