mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-11 09:36:10 +02:00
MG: fixed sizing/moving of non visual components
git-svn-id: trunk@3534 -
This commit is contained in:
parent
17b5d70d0b
commit
dcf903b4aa
@ -136,13 +136,6 @@ type
|
|||||||
TOnSelectionFormChanged = procedure(Sender: TObject;
|
TOnSelectionFormChanged = procedure(Sender: TObject;
|
||||||
OldForm, NewForm: TCustomForm) of object;
|
OldForm, NewForm: TCustomForm) of object;
|
||||||
|
|
||||||
TControlSelState = (cssOnlyNonVisualNeedsUpdate,
|
|
||||||
cssOnlyVisualNeedsUpdate,
|
|
||||||
cssBoundsNeedsUpdate,
|
|
||||||
cssBoundsNeedsSaving
|
|
||||||
);
|
|
||||||
TControlSelStates = set of TControlSelState;
|
|
||||||
|
|
||||||
TNearestInt = record
|
TNearestInt = record
|
||||||
Level: integer;
|
Level: integer;
|
||||||
Nearest: integer;
|
Nearest: integer;
|
||||||
@ -157,6 +150,14 @@ type
|
|||||||
|
|
||||||
TGuideLineType = (glLeft, glTop, glRight, glBottom);
|
TGuideLineType = (glLeft, glTop, glRight, glBottom);
|
||||||
|
|
||||||
|
TControlSelState = (cssOnlyNonVisualNeedsUpdate,
|
||||||
|
cssOnlyVisualNeedsUpdate,
|
||||||
|
cssBoundsNeedsUpdate,
|
||||||
|
cssBoundsNeedsSaving,
|
||||||
|
cssParentLevelNeedsUpdate
|
||||||
|
);
|
||||||
|
TControlSelStates = set of TControlSelState;
|
||||||
|
|
||||||
TControlSelection = class(TObject)
|
TControlSelection = class(TObject)
|
||||||
private
|
private
|
||||||
FControls: TList; // list of TSelectedComponent
|
FControls: TList; // list of TSelectedComponent
|
||||||
@ -187,6 +188,7 @@ type
|
|||||||
// caches
|
// caches
|
||||||
FCacheGuideLines: boolean;
|
FCacheGuideLines: boolean;
|
||||||
FGuideLinesCache: array[TGuideLineType] of TGuideLineCache;
|
FGuideLinesCache: array[TGuideLineType] of TGuideLineCache;
|
||||||
|
FParentLevel: integer;
|
||||||
|
|
||||||
FCustomForm: TCustomForm;
|
FCustomForm: TCustomForm;
|
||||||
FGrabbers: array[TGrabIndex] of TGrabber;
|
FGrabbers: array[TGrabIndex] of TGrabber;
|
||||||
@ -235,6 +237,7 @@ type
|
|||||||
// snapping
|
// snapping
|
||||||
function CleanGridSizeX: integer;
|
function CleanGridSizeX: integer;
|
||||||
function CleanGridSizeY: integer;
|
function CleanGridSizeY: integer;
|
||||||
|
function ComponentAlignable(AComponent: TComponent): boolean;
|
||||||
procedure ImproveNearestInt(var NearestInt: TNearestInt; Candidate: integer);
|
procedure ImproveNearestInt(var NearestInt: TNearestInt; Candidate: integer);
|
||||||
procedure FindNearestGridX(var NearestInt: TNearestInt);
|
procedure FindNearestGridX(var NearestInt: TNearestInt);
|
||||||
procedure FindNearestGridY(var NearestInt: TNearestInt);
|
procedure FindNearestGridY(var NearestInt: TNearestInt);
|
||||||
@ -295,6 +298,7 @@ type
|
|||||||
procedure DrawGuideLines(DC: TDesignerDeviceContext);
|
procedure DrawGuideLines(DC: TDesignerDeviceContext);
|
||||||
property CacheGuideLines: boolean read FCacheGuideLines write SetCacheGuideLines;
|
property CacheGuideLines: boolean read FCacheGuideLines write SetCacheGuideLines;
|
||||||
procedure InvalidGuideLinesCache;
|
procedure InvalidGuideLinesCache;
|
||||||
|
function ParentLevel: integer;
|
||||||
|
|
||||||
property GrabberSize:integer read FGrabberSize write SetGrabberSize;
|
property GrabberSize:integer read FGrabberSize write SetGrabberSize;
|
||||||
property GrabberColor: TColor read FGrabberColor write FGrabberColor;
|
property GrabberColor: TColor read FGrabberColor write FGrabberColor;
|
||||||
@ -401,9 +405,13 @@ end;
|
|||||||
|
|
||||||
procedure TSelectedControl.SetBounds(ALeft, ATop, AWidth, AHeight: integer);
|
procedure TSelectedControl.SetBounds(ALeft, ATop, AWidth, AHeight: integer);
|
||||||
begin
|
begin
|
||||||
if FComponent is TControl then
|
if FComponent is TControl then begin
|
||||||
TControl(FComponent).SetBounds(ALeft, ATop, AWidth, AHeight)
|
TControl(FComponent).SetBounds(ALeft, ATop, AWidth, AHeight);
|
||||||
else begin
|
FCachedLeft:=ALeft;
|
||||||
|
FCachedTop:=ATop;
|
||||||
|
FCachedWidth:=AWidth;
|
||||||
|
FCachedHeight:=AHeight;
|
||||||
|
end else begin
|
||||||
Left:=ALeft;
|
Left:=ALeft;
|
||||||
Top:=ATop;
|
Top:=ATop;
|
||||||
end;
|
end;
|
||||||
@ -453,7 +461,7 @@ begin
|
|||||||
if FComponent is TControl then
|
if FComponent is TControl then
|
||||||
TControl(FComponent).Left:=Aleft
|
TControl(FComponent).Left:=Aleft
|
||||||
else
|
else
|
||||||
LongRec(FComponent.DesignInfo).Lo:=ALeft;
|
LongRec(FComponent.DesignInfo).Lo:=Min(32000,Max(0,ALeft));
|
||||||
FCachedLeft:=ALeft;
|
FCachedLeft:=ALeft;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -470,7 +478,7 @@ begin
|
|||||||
if FComponent is TControl then
|
if FComponent is TControl then
|
||||||
TControl(FComponent).Top:=ATop
|
TControl(FComponent).Top:=ATop
|
||||||
else
|
else
|
||||||
LongRec(FComponent.DesignInfo).Hi:=ATop;
|
LongRec(FComponent.DesignInfo).Hi:=Min(32000,Max(0,ATop));
|
||||||
FCachedTop:=ATop;
|
FCachedTop:=ATop;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -536,7 +544,8 @@ begin
|
|||||||
FChangedDuringLock:=false;
|
FChangedDuringLock:=false;
|
||||||
FRubberbandActive:=false;
|
FRubberbandActive:=false;
|
||||||
FNotSaveBounds:=false;
|
FNotSaveBounds:=false;
|
||||||
FStates:=[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate];
|
FStates:=[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate,
|
||||||
|
cssParentLevelNeedsUpdate];
|
||||||
fCacheGuideLines:=true;
|
fCacheGuideLines:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -712,7 +721,7 @@ begin
|
|||||||
if NewHeight<1 then NewHeight:=1;
|
if NewHeight<1 then NewHeight:=1;
|
||||||
Items[i].SetFormRelativeBounds(NewLeft,NewTop,NewWidth,NewHeight);
|
Items[i].SetFormRelativeBounds(NewLeft,NewTop,NewWidth,NewHeight);
|
||||||
{$IFDEF VerboseDesigner}
|
{$IFDEF VerboseDesigner}
|
||||||
writeln(' i=',i,
|
writeln(' i=',i,' ',Items[i].Component.Name,
|
||||||
' ',Items[i].Left,',',Items[i].Top,',',Items[i].Width,',',Items[i].Height);
|
' ',Items[i].Left,',',Items[i].Top,',',Items[i].Width,',',Items[i].Height);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
@ -762,6 +771,31 @@ begin
|
|||||||
if Result<1 then Result:=1;
|
if Result<1 then Result:=1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TControlSelection.ComponentAlignable(AComponent: TComponent): boolean;
|
||||||
|
var
|
||||||
|
CurParentLevel: integer;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
if AComponent=nil then exit;
|
||||||
|
if AComponent is TControl then begin
|
||||||
|
if csNoDesignVisible in TControl(AComponent).ControlStyle then exit;
|
||||||
|
if Count>0 then begin
|
||||||
|
if OnlyNonVisualComponentsSelected then exit;
|
||||||
|
end;
|
||||||
|
if ParentLevel>0 then begin
|
||||||
|
CurParentLevel:=GetParentLevel(TControl(AComponent));
|
||||||
|
if CurParentLevel<>ParentLevel then exit;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
if Count>0 then begin
|
||||||
|
if OnlyVisualComponentsSelected then exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if IsSelected(AComponent) then exit;
|
||||||
|
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TControlSelection.ImproveNearestInt(var NearestInt: TNearestInt;
|
procedure TControlSelection.ImproveNearestInt(var NearestInt: TNearestInt;
|
||||||
Candidate: integer);
|
Candidate: integer);
|
||||||
begin
|
begin
|
||||||
@ -856,6 +890,7 @@ begin
|
|||||||
MaxDist:=(CleanGridSizeX+1) div 2;
|
MaxDist:=(CleanGridSizeX+1) div 2;
|
||||||
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
||||||
AComponent:=FCustomForm.Components[i];
|
AComponent:=FCustomForm.Components[i];
|
||||||
|
if not ComponentAlignable(AComponent) then exit;
|
||||||
if IsSelected(AComponent) then continue;
|
if IsSelected(AComponent) then continue;
|
||||||
CurLeft:=GetParentFormRelativeTopLeft(AComponent).X;
|
CurLeft:=GetParentFormRelativeTopLeft(AComponent).X;
|
||||||
CurDist:=Abs(CurLeft-NearestInt.Level);
|
CurDist:=Abs(CurLeft-NearestInt.Level);
|
||||||
@ -874,6 +909,7 @@ begin
|
|||||||
MaxDist:=(CleanGridSizeX+1) div 2;
|
MaxDist:=(CleanGridSizeX+1) div 2;
|
||||||
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
||||||
AComponent:=FCustomForm.Components[i];
|
AComponent:=FCustomForm.Components[i];
|
||||||
|
if not ComponentAlignable(AComponent) then exit;
|
||||||
if IsSelected(AComponent) then continue;
|
if IsSelected(AComponent) then continue;
|
||||||
CurRight:=GetParentFormRelativeTopLeft(AComponent).X
|
CurRight:=GetParentFormRelativeTopLeft(AComponent).X
|
||||||
+GetComponentWidth(AComponent);
|
+GetComponentWidth(AComponent);
|
||||||
@ -893,6 +929,7 @@ begin
|
|||||||
MaxDist:=(CleanGridSizeY+1) div 2;
|
MaxDist:=(CleanGridSizeY+1) div 2;
|
||||||
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
||||||
AComponent:=FCustomForm.Components[i];
|
AComponent:=FCustomForm.Components[i];
|
||||||
|
if not ComponentAlignable(AComponent) then exit;
|
||||||
if IsSelected(AComponent) then continue;
|
if IsSelected(AComponent) then continue;
|
||||||
CurTop:=GetParentFormRelativeTopLeft(AComponent).Y;
|
CurTop:=GetParentFormRelativeTopLeft(AComponent).Y;
|
||||||
CurDist:=Abs(CurTop-NearestInt.Level);
|
CurDist:=Abs(CurTop-NearestInt.Level);
|
||||||
@ -911,6 +948,7 @@ begin
|
|||||||
MaxDist:=(CleanGridSizeY+1) div 2;
|
MaxDist:=(CleanGridSizeY+1) div 2;
|
||||||
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
for i:=0 to FCustomForm.ComponentCount-1 do begin
|
||||||
AComponent:=FCustomForm.Components[i];
|
AComponent:=FCustomForm.Components[i];
|
||||||
|
if not ComponentAlignable(AComponent) then exit;
|
||||||
if IsSelected(AComponent) then continue;
|
if IsSelected(AComponent) then continue;
|
||||||
CurBottom:=GetParentFormRelativeTopLeft(AComponent).Y
|
CurBottom:=GetParentFormRelativeTopLeft(AComponent).Y
|
||||||
+GetComponentHeight(AComponent);
|
+GetComponentHeight(AComponent);
|
||||||
@ -1150,6 +1188,19 @@ begin
|
|||||||
FGuideLinesCache[t].CacheValid:=false;
|
FGuideLinesCache[t].CacheValid:=false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TControlSelection.ParentLevel: integer;
|
||||||
|
begin
|
||||||
|
if (cssParentLevelNeedsUpdate in FStates) then begin
|
||||||
|
if (Count>0) and OnlyVisualComponentsSelected
|
||||||
|
and (Items[0].Component is TControl) then
|
||||||
|
FParentLevel:=GetParentLevel(TControl(Items[0].Component))
|
||||||
|
else
|
||||||
|
FParentLevel:=0;
|
||||||
|
Exclude(FStates,cssParentLevelNeedsUpdate);
|
||||||
|
end;
|
||||||
|
Result:=FParentLevel;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TControlSelection.FindNearestGridX(var NearestInt: TNearestInt);
|
procedure TControlSelection.FindNearestGridX(var NearestInt: TNearestInt);
|
||||||
var GridSizeX, NearestGridX: integer;
|
var GridSizeX, NearestGridX: integer;
|
||||||
begin
|
begin
|
||||||
@ -1245,7 +1296,8 @@ begin
|
|||||||
NewSelectedControl:=TSelectedControl.Create(AComponent);
|
NewSelectedControl:=TSelectedControl.Create(AComponent);
|
||||||
if NewSelectedControl.ParentForm<>FCustomForm then Clear;
|
if NewSelectedControl.ParentForm<>FCustomForm then Clear;
|
||||||
Result:=FControls.Add(NewSelectedControl);
|
Result:=FControls.Add(NewSelectedControl);
|
||||||
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate];
|
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate,
|
||||||
|
cssParentLevelNeedsUpdate];
|
||||||
if Count=1 then SetCustomForm;
|
if Count=1 then SetCustomForm;
|
||||||
DoChange;
|
DoChange;
|
||||||
UpdateBounds;
|
UpdateBounds;
|
||||||
@ -1277,7 +1329,8 @@ begin
|
|||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
Items[Index].Free;
|
Items[Index].Free;
|
||||||
FControls.Delete(Index);
|
FControls.Delete(Index);
|
||||||
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate];
|
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate,
|
||||||
|
cssParentLevelNeedsUpdate];
|
||||||
if Count=0 then SetCustomForm;
|
if Count=0 then SetCustomForm;
|
||||||
UpdateBounds;
|
UpdateBounds;
|
||||||
SaveBounds;
|
SaveBounds;
|
||||||
@ -1291,7 +1344,8 @@ begin
|
|||||||
if FControls.Count=0 then exit;
|
if FControls.Count=0 then exit;
|
||||||
for i:=0 to FControls.Count-1 do Items[i].Free;
|
for i:=0 to FControls.Count-1 do Items[i].Free;
|
||||||
FControls.Clear;
|
FControls.Clear;
|
||||||
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate];
|
FStates:=FStates+[cssOnlyNonVisualNeedsUpdate,cssOnlyVisualNeedsUpdate,
|
||||||
|
cssParentLevelNeedsUpdate];
|
||||||
FCustomForm:=nil;
|
FCustomForm:=nil;
|
||||||
UpdateBounds;
|
UpdateBounds;
|
||||||
SaveBounds;
|
SaveBounds;
|
||||||
@ -1602,6 +1656,11 @@ var i:integer;
|
|||||||
var ALeft,ATop,ARight,ABottom:integer;
|
var ALeft,ATop,ARight,ABottom:integer;
|
||||||
Origin:TPoint;
|
Origin:TPoint;
|
||||||
begin
|
begin
|
||||||
|
if (AComponent is TControl)
|
||||||
|
and (csNoDesignVisible in TControl(AComponent).ControlStyle) then begin
|
||||||
|
Result:=false;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
Origin:=GetParentFormRelativeTopLeft(AComponent);
|
Origin:=GetParentFormRelativeTopLeft(AComponent);
|
||||||
ALeft:=Origin.X;
|
ALeft:=Origin.X;
|
||||||
ATop:=Origin.Y;
|
ATop:=Origin.Y;
|
||||||
|
@ -94,7 +94,7 @@ function GetComponentTop(AComponent: TComponent): integer;
|
|||||||
function GetComponentWidth(AComponent: TComponent): integer;
|
function GetComponentWidth(AComponent: TComponent): integer;
|
||||||
function GetComponentHeight(AComponent: TComponent): integer;
|
function GetComponentHeight(AComponent: TComponent): integer;
|
||||||
|
|
||||||
|
function GetParentLevel(AControl: TControl): integer;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -245,6 +245,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function GetParentLevel(AControl: TControl): integer;
|
||||||
|
begin
|
||||||
|
Result:=0;
|
||||||
|
while AControl<>nil do begin
|
||||||
|
inc(Result);
|
||||||
|
AControl:=AControl.Parent;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TDesignerDeviceContext }
|
{ TDesignerDeviceContext }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user