lcl: cleanup and format the splitter code

git-svn-id: trunk@26435 -
This commit is contained in:
paul 2010-07-03 07:40:21 +00:00
parent 946f34ba8f
commit f4a3839b99
2 changed files with 187 additions and 195 deletions

View File

@ -471,10 +471,8 @@ type
FSplitterStartMouseXY: TPoint; // in screen coordinates
FSplitterStartLeftTop: TPoint; // in screen coordinates
function GetResizeControl: TControl;
procedure SetAutoSnap(const AValue: boolean);
procedure SetBeveled(const AValue: boolean);
procedure SetMinSize(const AValue: integer);
procedure SetResizeStyle(const AValue: TResizeStyle);
protected
class procedure WSRegisterClass; override;
procedure CheckAlignment;
@ -504,14 +502,14 @@ type
function GetSplitterPosition: integer;
public
property Align default alLeft;
property AutoSnap: boolean read FAutoSnap write SetAutoSnap default true;
property AutoSnap: boolean read FAutoSnap write FAutoSnap default true;
property Beveled: boolean read FBeveled write SetBeveled default false;
property Cursor default crHSplit;
property MinSize: integer read FMinSize write SetMinSize default 30;
property OnCanResize: TCanResizeEvent read FOnCanResize write FOnCanResize;
property OnMoved: TNotifyEvent read FOnMoved write FOnMoved;
property ResizeAnchor: TAnchorKind read FResizeAnchor write SetResizeAnchor default akLeft;
property ResizeStyle: TResizeStyle read FResizeStyle write SetResizeStyle default rsUpdate;
property ResizeStyle: TResizeStyle read FResizeStyle write FResizeStyle default rsUpdate;
end;

View File

@ -28,7 +28,8 @@ var
begin
Result := nil;
count := Control.Parent.ControlCount;
if count > 0 then begin
if count > 0 then
begin
fRect := Control.BoundsRect;
case Control.Align of
alTop: begin
@ -55,13 +56,13 @@ begin
end;
end; // case
Dec(count);
for i := 0 to count do begin
for i := 0 to count do
begin
CurControl := Control.Parent.Controls[i];
if (CurControl <> Control)
and CurControl.Visible
and (CurControl.Align in alignList)
and (PtInRect(CurControl.BoundsRect, fPoint))
then Result := CurControl;
if (CurControl <> Control) and
CurControl.Visible and
(CurControl.Align in alignList) and
(PtInRect(CurControl.BoundsRect, fPoint)) then Result := CurControl;
if Assigned(Result) then Break;
end; // for i
end;
@ -74,21 +75,17 @@ function FindVirtualOppositeControl(Control: TControl): TControl;
Result := False;
case Control.Align of
alTop:
if (CurControl.Align = Control.Align)
and (CurControl.Top >= Control.BoundsRect.Bottom)
then Result := True;
if (CurControl.Align = Control.Align) and
(CurControl.Top >= Control.BoundsRect.Bottom) then Result := True;
alBottom:
if (CurControl.Align = Control.Align)
and (CurControl.BoundsRect.Bottom <= Control.Top)
then Result := True;
if (CurControl.Align = Control.Align) and
(CurControl.BoundsRect.Bottom <= Control.Top) then Result := True;
alLeft:
if (CurControl.Align = Control.Align)
and (CurControl.Left >= Control.BoundsRect.Right)
then Result := True;
if (CurControl.Align = Control.Align) and
(CurControl.Left >= Control.BoundsRect.Right) then Result := True;
alRight:
if (CurControl.Align = Control.Align)
and (CurControl.BoundsRect.Right <= Control.Left)
then Result := True;
if (CurControl.Align = Control.Align) and
(CurControl.BoundsRect.Right <= Control.Left) then Result := True;
end;
end;
@ -109,14 +106,17 @@ var
begin
Result := nil;
count := Control.Parent.ControlCount;
if count > 0 then begin
if count > 0 then
begin
Dec(count);
for i := 0 to count do begin
for i := 0 to count do
begin
CurControl := Control.Parent.Controls[i];
if (CurControl <> Control) then begin
if ((Result = nil) and OppositeControl(CurControl, Control))
or (Assigned(Result) and CompPos(CurControl, Result))
then Result := CurControl;
if (CurControl <> Control) then
begin
if ((Result = nil) and OppositeControl(CurControl, Control)) or
(Assigned(Result) and CompPos(CurControl, Result)) then
Result := CurControl;
end;
end; // for i
end;
@ -124,24 +124,12 @@ end;
{ TCustomSplitter }
procedure TCustomSplitter.SetResizeStyle(const AValue: TResizeStyle);
begin
if FResizeStyle=AValue then exit;
FResizeStyle:=AValue;
end;
class procedure TCustomSplitter.WSRegisterClass;
begin
inherited WSRegisterClass;
RegisterCustomSplitter;
end;
procedure TCustomSplitter.SetAutoSnap(const AValue: boolean);
begin
if FAutoSnap=AValue then exit;
FAutoSnap:=AValue;
end;
function TCustomSplitter.GetResizeControl: TControl;
begin
if Align in [alLeft,alRight,alTop,alBottom] then
@ -189,8 +177,8 @@ var
function GetControlSize(Control: TControl): Integer;
begin
Result := 0;
if Assigned(Control)
then case ResizeAnchor of
if Assigned(Control) then
case ResizeAnchor of
akLeft, akRight: Result := Control.Width;
akTop, akBottom: Result := Control.Height;
end;
@ -246,8 +234,8 @@ var
if NewSize > EndSize then NewSize := EndSize;
if NewSize < StartSize then NewSize := StartSize;
if fAutoSnap and (NewSize < fMinSize)
then NewSize := StartSize;
if AutoSnap and (NewSize < fMinSize) then
NewSize := StartSize;
Result := NewSize;
end;
@ -267,12 +255,13 @@ var
count: Integer;
begin
Result := nil;
for count := Parent.ControlCount-1 downto 0 do begin
for count := Parent.ControlCount - 1 downto 0 do
begin
CurControl := Parent.Controls[count];
if (CurControl <> Self)
and ((CurControl.Align = alClient)
or ((Self.Align in [alTop,alBottom])
and (CurControl.Align in [alLeft,alRight]))) then begin
if (CurControl <> Self) and
((CurControl.Align = alClient) or ((Self.Align in [alTop,alBottom]) and
(CurControl.Align in [alLeft,alRight]))) then
begin
Result := CurControl;
Break;
end;
@ -284,7 +273,8 @@ var
CurControl: TControl;
begin
CurControl := Control;
while Assigned(CurControl) do begin
while Assigned(CurControl) do
begin
Control := CurControl;
CurControl := FindOppositeControl(Control);
end;
@ -295,12 +285,14 @@ var
// returns the maximum size of the CurResizeControl due to parent's client
// area
begin
if ResizeAnchor in [akLeft,akRight] then begin
if ResizeAnchor in [akLeft, akRight] then
begin
if ResizeAnchor = akRight then
Result := CurResizeControl.Left + CurResizeControl.Width - Width
else
Result := Parent.ClientWidth - CurResizeControl.Left - Width;
end else begin
end else
begin
if ResizeAnchor = akBottom then
Result := CurResizeControl.Top + CurResizeControl.Height - Height
else
@ -329,7 +321,8 @@ begin
//DebugLn('TCustomSplitter.MoveSplitter ',DbgSName(Self),' Offset=',dbgs(Offset));
if Offset = 0 then Exit;
if Align in [alLeft,alTop,alRight,alBottom] then begin
if Align in [alLeft, alTop, alRight, alBottom] then
begin
// aligned Splitter
// -> consider aligned siblings for minimum and maximum movement
@ -340,42 +333,40 @@ begin
// calculate minimum size
StartSize := 1;
if not fAutoSnap
then Inc(StartSize,
Max(fMinSize, GetControlConstraintsMinSize(CurResizeControl)));
if not AutoSnap then
Inc(StartSize, Max(FMinSize, GetControlConstraintsMinSize(CurResizeControl)));
if StartSize > 1 then Dec(StartSize);
// calculate maximum size
if Assigned(CurOtherResizeControl)
then EndSize := GetControlSize(CurResizeControl)
+ GetControlSize(CurOtherResizeControl)
- Max(fMinSize, GetControlConstraintsMinSize(CurOtherResizeControl))
else begin
if Assigned(CurOtherResizeControl) then
EndSize := GetControlSize(CurResizeControl) +
GetControlSize(CurOtherResizeControl) -
Max(fMinSize, GetControlConstraintsMinSize(CurOtherResizeControl))
else
begin
VirtualOppositeControl := FindVirtualOppositeControl(Self);
LastControl := FindLastControl(Self);
case ResizeAnchor of
akLeft, akTop: begin
if Assigned(VirtualOppositeControl) then
akLeft, akTop:
begin
EndSize := GetControlSize(CurResizeControl)
+ (GetControlMinPos(VirtualOppositeControl)
- (GetControlMinPos(LastControl)
+ GetControlSize(LastControl)));
end
else EndSize := GetControlSize(CurResizeControl)
+ (GetParentClientSize
- GetControlMinPos(LastControl)
- GetControlSize(LastControl))
if Assigned(VirtualOppositeControl) then
EndSize := GetControlSize(CurResizeControl) +
(GetControlMinPos(VirtualOppositeControl) -
(GetControlMinPos(LastControl) + GetControlSize(LastControl)))
else
EndSize := GetControlSize(CurResizeControl) +
(GetParentClientSize -
GetControlMinPos(LastControl) - GetControlSize(LastControl))
end;
akRight, akBottom: begin
akRight, akBottom:
begin
if Assigned(VirtualOppositeControl) then
EndSize := GetControlSize(CurResizeControl)
+ (GetControlMinPos(LastControl)
- (GetControlMinPos(VirtualOppositeControl)
+ GetControlSize(VirtualOppositeControl)))
else EndSize := GetControlSize(CurResizeControl)
+ GetControlMinPos(LastControl);
EndSize := GetControlSize(CurResizeControl) +
(GetControlMinPos(LastControl) -
(GetControlMinPos(VirtualOppositeControl) + GetControlSize(VirtualOppositeControl)))
else
EndSize := GetControlSize(CurResizeControl) + GetControlMinPos(LastControl);
end;
end;
end;
@ -384,37 +375,37 @@ begin
NewSize := CalcNewSize(StartSize, EndSize, Offset);
// OnCanResize event
if CheckNewSize(NewSize)
then SetAlignControlSize(NewSize);
if CheckNewSize(NewSize) then
SetAlignControlSize(NewSize);
end else begin
end else
begin
// anchored Splitter
// -> consider anchored siblings for minimum and maximum movement
// OffsetMaxLower = maximum the Splitter can be moved top/left
OffsetMaxLower := Max(0,GetControlMinPos(Self)-fMinSize);
OffsetMaxLower := Max(0, GetControlMinPos(Self) - FMinSize);
// OffsetMaxUpper = maximum the Splitter can be moved bottom/right
OffsetMaxUpper := Max(0,GetParentsClientSize
-GetControlSize(Self)-GetControlMinPos(Self));
OffsetMaxUpper := Max(0, GetParentsClientSize -GetControlSize(Self) - GetControlMinPos(Self));
//DebugLn(['TCustomSplitter.MoveSplitter OffsetMaxLower=',OffsetMaxLower,' OffsetMaxUpper=',OffsetMaxUpper]);
for i:=0 to AnchoredControlCount-1 do begin
for i := 0 to AnchoredControlCount - 1 do
begin
CurResizeControl := AnchoredControls[i];
//debugln('TCustomSplitter.MoveSplitter ',DbgSName(Self),' CurResizeControl=',DbgSName(CurResizeControl));
if (CurResizeControl.AnchorSide[ResizeAnchor].Control=Self)
or (CurResizeControl.AnchorSide[OppositeAnchor[ResizeAnchor]].Control=Self)
then begin
if (CurResizeControl.AnchorSide[ResizeAnchor].Control = Self) or
(CurResizeControl.AnchorSide[OppositeAnchor[ResizeAnchor]].Control = Self) then
begin
// this control uses this Splitter as anchor
// => moving the Splitter will resize CurResizeControl
// => consider the constraints of CurResizeControl
// for minimum and maximum movement
// calculate how much the CurResizeControl can be shrinked
CurMaxShrink:=Max(0,GetControlSize(CurResizeControl)-
GetControlConstraintsMinSize(CurResizeControl));
CurMaxShrink := Max(0, GetControlSize(CurResizeControl) - GetControlConstraintsMinSize(CurResizeControl));
// calculate how much the CurResizeControl can be enlarged
CurMaxEnlarge:=Max(0,GetControlConstraintsMaxSize(CurResizeControl)
-GetControlSize(CurResizeControl));
if CurMaxEnlarge=0 then begin
CurMaxEnlarge := Max(0, GetControlConstraintsMaxSize(CurResizeControl) - GetControlSize(CurResizeControl));
if CurMaxEnlarge=0 then
begin
CurMaxEnlarge := GetParentsClientSize;
if GetControlMinPos(CurResizeControl) < 0 then
dec(CurMaxEnlarge, GetControlMinPos(CurResizeControl));
@ -422,13 +413,15 @@ begin
//debugln('TCustomSplitter.MoveSplitter ',DbgSName(Self),' CurResizeControl=',DbgSName(CurResizeControl),' CurMaxShrink=',dbgs(CurMaxShrink),' CurMaxEnlarge=',dbgs(CurMaxEnlarge),' ConstraintsMax=',dbgs(GetControlConstraintsMaxSize(CurResizeControl)));
// apply to the offset boundaries
if (CurResizeControl.AnchorSide[akLeft].Control=Self)
or (CurResizeControl.AnchorSide[akTop].Control=Self) then begin
if (CurResizeControl.AnchorSide[akLeft].Control = Self) or
(CurResizeControl.AnchorSide[akTop].Control = Self) then
begin
if CurMaxShrink > 0 then
OffsetMaxLower := Min(OffsetMaxLower, CurMaxShrink);
if CurMaxEnlarge > 0 then
OffsetMaxUpper := Min(OffsetMaxUpper, CurMaxEnlarge);
end else begin
end else
begin
if CurMaxEnlarge > 0 then
OffsetMaxLower := Min(OffsetMaxLower, CurMaxEnlarge);
if CurMaxShrink > 0 then
@ -465,20 +458,20 @@ end;
procedure TCustomSplitter.SetBeveled(const AValue: boolean);
begin
if FBeveled=AValue then exit;
if FBeveled = AValue then Exit;
FBeveled := AValue;
Invalidate;
end;
procedure TCustomSplitter.SetMinSize(const AValue: integer);
begin
if (FMinSize=AValue) or (AValue<1) then exit;
if (FMinSize=AValue) or (AValue < 1) then Exit;
FMinSize := AValue;
end;
procedure TCustomSplitter.SetResizeAnchor(const AValue: TAnchorKind);
begin
if FResizeAnchor=AValue then exit;
if FResizeAnchor = AValue then Exit;
FResizeAnchor := AValue;
if ResizeAnchor in [akLeft, akRight] then
Cursor := crHSplit
@ -490,8 +483,10 @@ end;
procedure TCustomSplitter.SetResizeControl(const AValue: TControl);
begin
if Align in [alLeft,alRight,alTop,alBottom] then begin
if AValue<>nil then begin
if Align in [alLeft, alRight, alTop, alBottom] then
begin
if AValue <> nil then
begin
case Align of
alLeft: Left := AValue.Left + 1;
alTop: Top := AValue.Top + 1;
@ -499,14 +494,14 @@ begin
alBottom: Top := AValue.Top - 1;
end;
end;
end else begin
end
else
AnchorSide[ResizeAnchor].Control := AValue;
end;
end;
procedure TCustomSplitter.StartSplitterMove(const MouseXY: TPoint);
begin
if FSplitDragging then exit;
if FSplitDragging then Exit;
FSplitDragging := True;
FSplitterStartMouseXY := MouseXY;
FSplitterStartLeftTop := Point(Left, Top);
@ -537,11 +532,9 @@ begin
GetCursorPos(MousePos);
case ResizeAnchor of
akLeft, akRight:
Offset := (MousePos.X - FSplitterStartMouseXY.X)
- (Self.Left - FSplitterStartLeftTop.X);
Offset := (MousePos.X - FSplitterStartMouseXY.X) - (Self.Left - FSplitterStartLeftTop.X);
akTop, akBottom:
Offset := (MousePos.Y - FSplitterStartMouseXY.Y)
- (Self.Top - FSplitterStartLeftTop.Y);
Offset := (MousePos.Y - FSplitterStartMouseXY.Y) - (Self.Top - FSplitterStartLeftTop.Y);
end;
if Offset = 0 then Exit;
@ -571,8 +564,8 @@ var
procedure FindNearerControl(CurValue, Limit: integer);
begin
if (CurValue<=Limit)
and ((Result=nil) or (BestValue<CurValue)) then begin
if (CurValue <= Limit) and ((Result = nil) or (BestValue < CurValue)) then
begin
BestValue := CurValue;
Result := CurControl;
end;
@ -583,12 +576,12 @@ begin
BestValue:=0;
if (Parent = nil) then Exit;
if not (Align in [alLeft,alTop,alRight,alBottom]) then exit;
for i := Parent.ControlCount-1 downto 0 do begin
for i := Parent.ControlCount - 1 downto 0 do
begin
CurControl := Parent.Controls[i];
if (CurControl <> Self)
and (CurControl.Visible)
and ((CurControl.Align = Self.Align) or (CurControl.Align=alClient))
then begin
if (CurControl <> Self) and (CurControl.Visible) and
((CurControl.Align = Self.Align) or (CurControl.Align=alClient)) then
begin
case Self.Align of
alLeft: FindNearerControl(CurControl.Left+CurControl.Width,Left);
alTop: FindNearerControl(CurControl.Top+CurControl.Height,Top);
@ -683,8 +676,7 @@ begin
alRight: FResizeAnchor:=akRight;
alBottom: FResizeAnchor:=akBottom;
end;
if ((Align = Value) and (OldResizeAnchor=FResizeAnchor))
or (Value=alClient) then
if ((Align = Value) and (OldResizeAnchor = FResizeAnchor)) or (Value = alClient) then
Exit;
OldWidth := Width;
OldHeight := Height;
@ -701,12 +693,15 @@ begin
CheckAlignment;
// lfm contains correct size already
if not (csLoading in ComponentState) then begin
if (OldResizeAnchor in [akLeft,akRight])=(ResizeAnchor in [akLeft,akRight])
then begin
if not (csLoading in ComponentState) then
begin
if (OldResizeAnchor in [akLeft,akRight])=(ResizeAnchor in [akLeft,akRight]) then
begin
// keep width and height
SetBounds(Left,Top,OldWidth,OldHeight);
end else begin
end
else
begin
// resize
if Align in [alLeft,alRight] then
Width:=OldHeight
@ -854,8 +849,7 @@ begin
Width := 5;
end;
procedure TCustomSplitter.AnchorSplitter(Kind: TAnchorKind; AControl: TControl
);
procedure TCustomSplitter.AnchorSplitter(Kind: TAnchorKind; AControl: TControl);
procedure AnchorSplitterSides(
ResizeSide,// the side of the Splitter, where AControl is touched and moved
@ -894,8 +888,8 @@ begin
akBottom: AnchorSplitterSides(akBottom, akTop, akLeft, akRight);
end;
if (OldResizeAnchor in [akLeft,akRight])=(ResizeAnchor in [akLeft,akRight])
then begin
if (OldResizeAnchor in [akLeft, akRight]) = (ResizeAnchor in [akLeft, akRight]) then
begin
// keep width and height
SetBounds(Left, Top, OldWidth, OldHeight);
end else begin