mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-06 05:18:00 +02:00
424 lines
11 KiB
PHP
424 lines
11 KiB
PHP
// included by forms.pp
|
|
|
|
{
|
|
*****************************************************************************
|
|
* *
|
|
* This file is part of the Lazarus Component Library (LCL) *
|
|
* *
|
|
* See the file COPYING.LCL, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
|
|
const
|
|
IntfBarKind: array[TScrollBarKind] of Integer = (SB_HORZ,SB_VERT);
|
|
|
|
procedure TControlScrollBar.SetPosition(const Value: Integer);
|
|
var
|
|
OldPosition: Integer;
|
|
begin
|
|
if Value < 0 then begin
|
|
SetPosition(0);
|
|
exit;
|
|
end;
|
|
|
|
If ControlAutoScroll then begin
|
|
if FAutoRange < 0 then
|
|
AutoCalcRange;
|
|
|
|
if Value > FAutoRange then begin
|
|
SetPosition(FAutoRange);
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
if Value>Range then begin
|
|
SetPosition(Range);
|
|
exit;
|
|
end;
|
|
|
|
if Value=FPosition then exit;
|
|
|
|
// scroll content of FControl
|
|
OldPosition:=FPosition;
|
|
FPosition := Value;
|
|
if Kind = sbVertical then
|
|
ScrollControlBy(0, OldPosition - FPosition)
|
|
else
|
|
ScrollControlBy(OldPosition - FPosition, 0);
|
|
|
|
// check that the new position is also set on the scrollbar
|
|
if HandleAllocated
|
|
and (GetScrollPos(ControlHandle, IntfBarKind[Kind]) <> FPosition) then
|
|
SetScrollPos(ControlHandle, IntfBarKind[Kind], FPosition, Visible);
|
|
end;
|
|
|
|
function TControlScrollBar.SmoothIsStored: boolean;
|
|
begin
|
|
Result:=FSmooth;
|
|
end;
|
|
|
|
function TControlScrollBar.GetIncrement: TScrollBarInc;
|
|
begin
|
|
Result:=FIncrement;
|
|
end;
|
|
|
|
function TControlScrollBar.GetPage: TScrollBarInc;
|
|
var ScrollInfo: TScrollInfo;
|
|
begin
|
|
if HandleAllocated and (not (FControl is TScrollingWinControl)) then begin
|
|
ScrollInfo.fMask:=SIF_PAGE;
|
|
GetScrollInfo(ControlHandle,IntfBarKind[Kind],ScrollInfo);
|
|
FPage:=ScrollInfo.nPage;
|
|
end;
|
|
Result:=FPage;
|
|
end;
|
|
|
|
function TControlScrollBar.GetPosition: Integer;
|
|
var ScrollInfo: TScrollInfo;
|
|
begin
|
|
if HandleAllocated and (not (FControl is TScrollingWinControl)) then begin
|
|
ScrollInfo.fMask:=SIF_POS;
|
|
GetScrollInfo(ControlHandle,IntfBarKind[Kind],ScrollInfo);
|
|
FPosition:=ScrollInfo.nPos;
|
|
end;
|
|
Result:=FPosition;
|
|
end;
|
|
|
|
function TControlScrollBar.GetRange: Integer;
|
|
var ScrollInfo: TScrollInfo;
|
|
begin
|
|
if HandleAllocated and (not (FControl is TScrollingWinControl)) then begin
|
|
ScrollInfo.fMask:=SIF_Range+SIF_Page;
|
|
GetScrollInfo(ControlHandle,IntfBarKind[Kind],ScrollInfo);
|
|
FRange:=ScrollInfo.nMax-ScrollInfo.nMin-integer(ScrollInfo.nPage);
|
|
end;
|
|
Result:=FRange;
|
|
end;
|
|
|
|
function TControlScrollBar.GetSmooth: Boolean;
|
|
begin
|
|
Result:=FSmooth;
|
|
end;
|
|
|
|
function TControlScrollBar.GetVisible: Boolean;
|
|
begin
|
|
if HandleAllocated and (not (FControl is TScrollingWinControl)) then begin
|
|
FVisible:=GetScrollbarVisible(Controlhandle,IntfBarKind[Kind]);
|
|
end;
|
|
Result:=FVisible;
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetIncrement(const AValue: TScrollBarInc);
|
|
begin
|
|
// This value is only used by the ScrollHandler procedure
|
|
FIncrement:=AValue;
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetPage(const AValue: TScrollBarInc);
|
|
begin
|
|
if FPage=AValue then exit;
|
|
FPage:=AValue;
|
|
ControlUpdateScrollBars;
|
|
end;
|
|
|
|
function TControlScrollBar.VisibleIsStored: boolean;
|
|
begin
|
|
Result:=FVisible;
|
|
end;
|
|
|
|
function TControlScrollBar.GetSize: integer;
|
|
var
|
|
KindID: integer;
|
|
begin
|
|
if Kind=sbHorizontal then
|
|
KindID:=SM_CXHSCROLL
|
|
else
|
|
KindID:=SM_CXVSCROLL;
|
|
if HandleAllocated then
|
|
Result:=LCLIntf.GetScrollBarSize(ControlHandle,KindID)
|
|
else
|
|
Result:=GetSystemMetrics(KindID);
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetRange(const Value: Integer);
|
|
begin
|
|
If Value < 0 then begin
|
|
Range := 0;
|
|
exit;
|
|
end;
|
|
if FRange=Value then exit;
|
|
FRange := Value;
|
|
ControlUpdateScrollBars;
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetSize(const AValue: integer);
|
|
begin
|
|
Raise EScrollBar.Create('[TControlScrollBar.SetPage] Size is readonly');
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetVisible(const Value: Boolean);
|
|
begin
|
|
if FVisible = Value then exit;
|
|
FVisible := Value;
|
|
ControlUpdateScrollBars;
|
|
end;
|
|
|
|
procedure TControlScrollBar.ScrollControlBy(DeltaX, DeltaY: integer);
|
|
begin
|
|
if FControl is TScrollingWinControl then
|
|
TScrollingWinControl(FControl).ScrollBy(DeltaX, DeltaY);
|
|
end;
|
|
|
|
procedure TControlScrollBar.SetSmooth(const Value: Boolean);
|
|
begin
|
|
// only used by the ScrollHandler procedure
|
|
FSmooth := Value;
|
|
end;
|
|
|
|
procedure TControlScrollBar.AutoCalcRange;
|
|
|
|
procedure AutoCalcVRange;
|
|
var
|
|
I : Integer;
|
|
TmpRange : Longint;
|
|
IncludeControl : Boolean;
|
|
begin
|
|
TmpRange := 0;
|
|
For I := 0 to FControl.ControlCount - 1 do
|
|
With FControl.Controls[I] do
|
|
if Visible then begin
|
|
IncludeControl := (Align = alTop) or (Align = alNone);
|
|
If IncludeControl then
|
|
TmpRange := Max(TmpRange, Top + Height);
|
|
end;
|
|
Range := TmpRange;
|
|
end;
|
|
|
|
procedure AutoCalcHRange;
|
|
var
|
|
I : Integer;
|
|
TmpRange : Longint;
|
|
IncludeControl : Boolean;
|
|
begin
|
|
TmpRange := 0;
|
|
For I := 0 to FControl.ControlCount - 1 do
|
|
With FControl.Controls[I] do
|
|
if Visible then begin
|
|
IncludeControl := (Align = alLeft) or (Align = alNone);
|
|
If IncludeControl then
|
|
TmpRange := Max(TmpRange, Left + Width);
|
|
end;
|
|
Range := TmpRange;
|
|
end;
|
|
|
|
begin
|
|
if ControlAutoScroll then begin
|
|
FVisible := True;
|
|
if Kind = sbVertical then
|
|
AutoCalcVRange
|
|
else
|
|
AutoCalcHRange;
|
|
ControlUpdateScrollBars;
|
|
end;
|
|
end;
|
|
|
|
procedure TControlScrollBar.UpdateScrollBar;
|
|
var
|
|
ScrollInfo: TScrollInfo;
|
|
SBSize : Longint;
|
|
OtherScrollbar: TControlScrollBar;
|
|
CurMax: Integer;
|
|
begin
|
|
FAutoRange := 0;
|
|
|
|
if FControl is TScrollingWinControl then begin
|
|
ScrollInfo.cbSize := SizeOf(ScrollInfo);
|
|
ScrollInfo.fMask := SIF_ALL;
|
|
ScrollInfo.nMin := 0;
|
|
ScrollInfo.nPos := FPosition;
|
|
ScrollInfo.nTrackPos := FPosition;
|
|
|
|
With TScrollingWinControl(FControl) do begin
|
|
// page
|
|
if Self.Kind=sbVertical then
|
|
FPage := Min(ClientHeight + 1,High(FPage))
|
|
else
|
|
FPage := Min(ClientWidth + 1,High(FPage));
|
|
ScrollInfo.nPage := FPage;
|
|
|
|
// range
|
|
if Visible then begin
|
|
OtherScrollbar:=GetOtherScrollBar;
|
|
If OtherScrollbar.FVisible then
|
|
SBSize := OtherScrollbar.Size
|
|
else
|
|
SBSize := 0;
|
|
if Kind=sbVertical then
|
|
FAutoRange := (FRange - ClientHeight)
|
|
*Shortint(FRange >= ClientHeight + SBSize)
|
|
else
|
|
FAutoRange := (FRange - ClientWidth)
|
|
*Shortint(FRange >= ClientWidth + SBSize);
|
|
ScrollInfo.nMax := FRange;
|
|
end
|
|
else
|
|
ScrollInfo.nMax := 0;
|
|
|
|
// visible
|
|
if Kind=sbVertical then
|
|
CurMax:=Height
|
|
else
|
|
CurMax:=Width;
|
|
If (Self.FVisible and not FAutoScroll)
|
|
or (FAutoScroll and (ScrollInfo.nMax > 0) and (ScrollInfo.nMax > CurMax))
|
|
then
|
|
Self.FVisible := True
|
|
else
|
|
Self.FVisible := False;
|
|
|
|
// transmit scollinfo to interface
|
|
if HandleAllocated then
|
|
SetScrollInfo(Handle, IntfBarKind[Kind], ScrollInfo, Self.FVisible);
|
|
end
|
|
end;
|
|
|
|
SetPosition(ScrollInfo.nTrackPos);
|
|
|
|
if FControl is TScrollingWinControl then begin
|
|
// I am not positive that this is right, but it apeared to be when I compared
|
|
// results to Delphi 4
|
|
if FSmooth then
|
|
FIncrement := FPage div 10;
|
|
end;
|
|
end;
|
|
|
|
function TControlScrollBar.ControlAutoScroll: boolean;
|
|
begin
|
|
if FControl is TScrollingWinControl then
|
|
Result:=TScrollingWinControl(FControl).AutoScroll
|
|
else
|
|
Result:=false;
|
|
end;
|
|
|
|
procedure TControlScrollBar.ScrollHandler(var Message: TLMScroll);
|
|
var
|
|
NewPos: Longint;
|
|
begin
|
|
If (csDesigning in FControl.ComponentState) then
|
|
exit; //prevent wierdness in IDE.
|
|
|
|
with Message do
|
|
begin
|
|
NewPos := FPosition;
|
|
case ScrollCode of
|
|
SB_LINEUP:
|
|
Dec(NewPos, FIncrement);
|
|
SB_LINEDOWN:
|
|
Inc(NewPos, FIncrement);
|
|
SB_PAGEUP:
|
|
Dec(NewPos, FPage);
|
|
SB_PAGEDOWN:
|
|
Inc(NewPos, FPage);
|
|
SB_THUMBPOSITION, SB_THUMBTRACK:
|
|
NewPos := Pos;
|
|
SB_TOP:
|
|
NewPos := 0;
|
|
SB_BOTTOM:
|
|
NewPos := Range;
|
|
end;
|
|
if NewPos < 0 then NewPos := 0;
|
|
if NewPos > Range then NewPos := Range;
|
|
SetPosition(NewPos);
|
|
end;
|
|
end;
|
|
|
|
procedure TControlScrollBar.ControlUpdateScrollBars;
|
|
begin
|
|
if csLoading in FControl.ComponentState then exit;
|
|
if FControl is TScrollingWinControl then
|
|
TScrollingWinControl(FControl).UpdateScrollBars;
|
|
end;
|
|
|
|
function TControlScrollBar.HandleAllocated: boolean;
|
|
begin
|
|
Result:=(FControl<>nil) and (FControl.HandleAllocated)
|
|
end;
|
|
|
|
function TControlScrollBar.ControlHandle: HWnd;
|
|
begin
|
|
Result:=FControl.Handle;
|
|
end;
|
|
|
|
constructor TControlScrollBar.Create(AControl: TWinControl;
|
|
AKind: TScrollBarKind);
|
|
begin
|
|
Inherited Create;
|
|
FControl := AControl;
|
|
FKind := AKind;
|
|
FPage := 80;
|
|
FIncrement := 8;
|
|
FPosition := 0;
|
|
FRange := 0;
|
|
FSmooth := false;
|
|
FVisible := false;
|
|
end;
|
|
|
|
procedure TControlScrollBar.Assign(Source: TPersistent);
|
|
begin
|
|
If Source is TControlScrollBar then begin
|
|
With Source as TControlScrollBar do begin
|
|
Self.Increment := Increment;
|
|
Self.Position := Position;
|
|
Self.Range := Range;
|
|
Self.Visible := Visible;
|
|
Self.Smooth := Smooth;
|
|
// page and size depend on FControl, so no need to copy them
|
|
end;
|
|
end
|
|
else
|
|
inherited Assign(Source);
|
|
end;
|
|
|
|
function TControlScrollBar.IsScrollBarVisible: Boolean;
|
|
begin
|
|
Result := (FControl <> nil) and FControl.HandleAllocated and
|
|
(FControl.Visible) and (Self.Visible);
|
|
end;
|
|
|
|
function TControlScrollBar.ScrollPos: Integer;
|
|
begin
|
|
if Visible then
|
|
Result:=Position
|
|
else
|
|
Result:=0;
|
|
end;
|
|
|
|
function TControlScrollBar.GetOtherScrollBar: TControlScrollBar;
|
|
begin
|
|
if Kind=sbVertical then
|
|
Result:=GetHorzScrollBar
|
|
else
|
|
Result:=GetVertSCrollbar;
|
|
end;
|
|
|
|
function TControlScrollBar.GetHorzScrollBar: TControlScrollBar;
|
|
begin
|
|
if FControl is TScrollingWinControl then
|
|
Result:=TScrollingWinControl(FControl).HorzScrollBar;
|
|
end;
|
|
|
|
function TControlScrollBar.GetVertScrollBar: TControlScrollBar;
|
|
begin
|
|
if FControl is TScrollingWinControl then
|
|
Result:=TScrollingWinControl(FControl).VertScrollBar;
|
|
end;
|
|
|
|
// included by forms.pp
|
|
|