// aOriginalContainerSize为原始布局大小。 // aLandscape为当前屏幕是否横屏。 // aFixContainerSize默认值为(0, 0)。修改X>0代表把Width缩放到指定大小,修改Y>0代表把Height缩放到指定大小。Width和Height与aLandscape有关。 procedure Change_ContainerOriginalSize(const aOriginalContainerSize: TPointF; aLandscape: Boolean; var aFixContainerSize: TPoint); virtual; public class var DefaultScaleOption_EnouthSize: TBambooFormScaleOption_EnoughSize; class var DefaultScaleOption_NoEnouthSize: TBambooFormScaleOption_NoEnoughSize; end;
implementation
{ TBambooScaledForm }
{$IFDEF NEXTGEN}
constructor TBambooScaledForm.Create(AOwner: TComponent); begin FInited := False; inherited Create(AOwner); end;
procedure TBambooScaledForm.Do_AfterResize; var aScaleOption: TBambooFormScaleOption; begin if csDesigning in ComponentState then Exit;
// 如果窗体的BorderStyle指明了允许改变大小,那么就让它自己处理。 if (Self.BorderStyle = TFmxFormBorderStyle.Sizeable) or (Self.BorderStyle = TFmxFormBorderStyle.SizeToolWin) or ((Self.BorderStyle = TFmxFormBorderStyle.Single) and (TBorderIcon.biMaximize in Self.BorderIcons)) then aScaleOption := TBambooFormScaleOption.bfsoContents else if (ClientWidth >= FOriginalContainerSize.X) and (ClientHeight >= FOriginalContainerSize.Y) then aScaleOption := Get_ScaleOption_EnouthSize else aScaleOption := Get_ScaleOption_NoEnouthSize; FScaleOption := aScaleOption; case FScaleOption of bfsoCenter: begin FOriginalLayout.Parent := FMainLayout; FOriginalLayout.Align := TAlignLayout.None; FOriginalLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); FOriginalLayout.Align := TAlignLayout.Center; FOriginalLayout.BringToFront; end; bfsoContents: begin FOriginalLayout.Parent := FMainLayout; FOriginalLayout.Align := TAlignLayout.Contents; FOriginalLayout.BringToFront; end; bfsoFit: begin FOriginalLayout.Parent := FMainLayout; FOriginalLayout.Align := TAlignLayout.None; FOriginalLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); FOriginalLayout.Align := TAlignLayout.Fit; FOriginalLayout.BringToFront; end; bfsoScale: begin FScaledLayout.Align := TAlignLayout.None; FScaledLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); FOriginalLayout.Align := TAlignLayout.None; FOriginalLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); FOriginalLayout.Parent := FScaledLayout; FScaledLayout.OriginalWidth := FOriginalContainerSize.X; FScaledLayout.OriginalHeight := FOriginalContainerSize.Y; FScaledLayout.Align := TAlignLayout.Fit; FScaledLayout.BringToFront; end; bfsoScroll: begin FOriginalLayout.Parent := FScrollBox; FOriginalLayout.Align := TAlignLayout.None; FOriginalLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); FScrollBox.BringToFront; end; end; end;
procedure TBambooScaledForm.Do_Change_ContainerOriginalSize(var aOriginalContainerSize: TPointF); var aFixContainerSize: TPoint; begin aFixContainerSize.X := 0; aFixContainerSize.Y := 0; Change_ContainerOriginalSize(aOriginalContainerSize, Screen.Height < Screen.Width, aFixContainerSize); if (aFixContainerSize.X <= 0) and (aFixContainerSize.Y <= 0) then Exit; if (aFixContainerSize.X > 0) and (aFixContainerSize.Y > 0) then begin aOriginalContainerSize.X := aFixContainerSize.X; aOriginalContainerSize.Y := aFixContainerSize.Y; end else if aFixContainerSize.X > 0 then begin aOriginalContainerSize.X := aFixContainerSize.X; aOriginalContainerSize.Y := Trunc(Self.ClientHeight * aFixContainerSize.X / Self.ClientWidth); end else begin aOriginalContainerSize.Y := aFixContainerSize.Y; aOriginalContainerSize.X := Trunc(Self.ClientWidth * aFixContainerSize.Y / Self.ClientHeight); end; end;
procedure TBambooScaledForm.Do_Init; var aList: TList<TControl>; i: Integer; begin if FInited then Exit; FInited := True; if csDesigning in ComponentState then Exit;
aList := TList<TControl>.Create; for i := 0 to ChildrenCount - 1 do begin if Children[i] is TControl then aList.Add(TControl(Children[i])); end;
FOriginalContainerSize := OriginalContainerSize; Do_Change_ContainerOriginalSize(FOriginalContainerSize); Self.BeginUpdate; FOriginalLayout := TLayout.Create(Self); FOriginalLayout.BeginUpdate; FOriginalLayout.Padding := Self.Padding; FOriginalLayout.SetBounds(0, 0, FOriginalContainerSize.X, FOriginalContainerSize.Y); for i := 0 to aList.Count - 1 do begin aList.Items[i].Parent := FOriginalLayout; end; aList.DisposeOf; FOriginalLayout.EndUpdate;
function TBambooScaledForm.Get_ScaleOption_EnouthSize: TBambooFormScaleOption_EnoughSize; begin Result := DefaultScaleOption_EnouthSize; end;
function TBambooScaledForm.Get_ScaleOption_NoEnouthSize: TBambooFormScaleOption_NoEnoughSize; begin Result := DefaultScaleOption_NoEnouthSize; end;
procedure TBambooScaledForm.Change_ContainerOriginalSize(const aOriginalContainerSize: TPointF; aLandscape: Boolean; var aFixContainerSize: TPoint); begin
end;
procedure Do_InitDefault; begin TBambooScaledForm.DefaultScaleOption_EnouthSize := TBambooFormScaleOption.bfsoCenter; TBambooScaledForm.DefaultScaleOption_NoEnouthSize := TBambooFormScaleOption.bfsoScale; end;