mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-21 09:39:31 +02:00
269 lines
7.4 KiB
PHP
269 lines
7.4 KiB
PHP
{%MainUnit ../stdctrls.pp}
|
|
|
|
{
|
|
TCustomScrollBar
|
|
|
|
*****************************************************************************
|
|
This file is part of the Lazarus Component Library (LCL)
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
|
for details about the license.
|
|
*****************************************************************************
|
|
}
|
|
|
|
|
|
|
|
{------------------------------------------------------------------------------}
|
|
{ function TCustomScrollBar.Create }
|
|
{------------------------------------------------------------------------------}
|
|
constructor TCustomScrollBar.Create(AOwner: TComponent);
|
|
begin
|
|
inherited Create(AOwner);
|
|
fCompStyle := csScrollBar;
|
|
with GetControlClassDefaultSize do
|
|
SetInitialBounds(0, 0, CX, CY);
|
|
TabStop := True;
|
|
ControlStyle := ControlStyle + [csFramed, csDoubleClicks, csOpaque]
|
|
- [csAcceptsControls, csDoubleClicks,
|
|
csCaptureMouse, csSetCaption];
|
|
FKind := sbHorizontal;
|
|
FPosition := 0;
|
|
FMin := 0;
|
|
FMax := 100;
|
|
FSmallChange := 1;
|
|
FLargeChange := 1;
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CreateParams(var Params: TCreateParams);
|
|
const
|
|
Kinds: array[TScrollBarKind] of DWORD = (SBS_HORZ, SBS_VERT);
|
|
begin
|
|
inherited CreateParams(Params);
|
|
Params.Style := Params.Style or Kinds[FKind];
|
|
FRTLFactor := 1
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CreateWnd;
|
|
var
|
|
ScrollInfo: TScrollInfo;
|
|
begin
|
|
inherited CreateWnd;
|
|
if not HandleAllocated then RaiseGDBException('TCustomScrollBar.CreateWnd HandleAllocated=false');
|
|
ScrollInfo.cbSize := SizeOf(ScrollInfo);
|
|
ScrollInfo.nMin := FMin;
|
|
ScrollInfo.nMax := FMax;
|
|
ScrollInfo.nPage := FPageSize;
|
|
ScrollInfo.fMask := SIF_PAGE or SIF_Range;
|
|
SetScrollInfo(Handle, SB_CTL, ScrollInfo, False);
|
|
if NotRightToLeft then
|
|
SetScrollPos(Handle, SB_CTL, FPosition, True)
|
|
else
|
|
SetScrollPos(Handle, SB_CTL, FMax - FPosition, True);
|
|
end;
|
|
|
|
function TCustomScrollBar.NotRightToLeft: Boolean;
|
|
begin
|
|
Result := True;
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetKind(Value: TScrollBarKind);
|
|
var
|
|
OldWidth: Integer;
|
|
OldHeight: Integer;
|
|
begin
|
|
if FKind = Value then Exit;
|
|
|
|
FKind := Value;
|
|
|
|
// the InterfaceConstraints need to get updated, even when loading
|
|
OldWidth:=Width;
|
|
OldHeight:=Height;
|
|
Constraints.UpdateInterfaceConstraints;
|
|
|
|
// switch width and height, but not when loading, because we assume that
|
|
// the lfm contains a consistent combination of kind and (width, height)
|
|
if (csLoading in ComponentState) then Exit;
|
|
|
|
if HandleAllocated then
|
|
TWSScrollBarClass(WidgetSetClass).SetKind(Self, FKind = sbHorizontal);
|
|
|
|
SetBounds(Left,Top,OldHeight,OldWidth);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetParams(APosition, AMin, AMax, APageSize: Integer);
|
|
var
|
|
ScrollInfo: TScrollInfo;
|
|
begin
|
|
if AMax < AMin then
|
|
raise EInvalidOperation.Create(rsScrollBarOutOfRange);
|
|
if APosition < AMin then APosition := AMin;
|
|
if APosition > AMax then APosition := AMax;
|
|
if APageSize < 0 then APageSize := 0;
|
|
if (FMin <> AMin) or (FMax <> AMax) or (APageSize <> FPageSize) then
|
|
begin
|
|
FMin := AMin;
|
|
FMax := AMax;
|
|
FPageSize := APageSize;
|
|
if HandleAllocated then
|
|
begin
|
|
ScrollInfo.fMask := SIF_PAGE or SIF_Range;
|
|
ScrollInfo.nMin := AMin;
|
|
ScrollInfo.nMax := AMax;
|
|
ScrollInfo.nPage := APageSize;
|
|
SetScrollInfo(Handle, SB_CTL, ScrollInfo, FPosition = APosition);
|
|
end;
|
|
end;
|
|
if FPosition <> APosition then
|
|
begin
|
|
FPosition := APosition;
|
|
if HandleAllocated then
|
|
if NotRightToLeft then
|
|
SetScrollPos(Handle, SB_CTL, FPosition, True)
|
|
else
|
|
SetScrollPos(Handle, SB_CTL, FMax - FPosition, True);
|
|
Change;
|
|
end;
|
|
if HandleAllocated then
|
|
TWSScrollBarClass(WidgetSetClass).SetParams(Self);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetParams(APosition, AMin, AMax: Integer);
|
|
begin
|
|
SetParams(APosition, AMin, AMax, FPageSize);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CalculatePreferredSize(var PreferredWidth,
|
|
PreferredHeight: integer; WithThemeSpace: Boolean);
|
|
begin
|
|
inherited CalculatePreferredSize(PreferredWidth, PreferredHeight,
|
|
WithThemeSpace);
|
|
if (Kind=sbHorizontal) and (PreferredHeight=0) then
|
|
PreferredHeight:=GetSystemMetrics(SM_CYHSCROLL);
|
|
if (Kind=sbVertical) and (PreferredWidth=0) then
|
|
PreferredWidth:=GetSystemMetrics(SM_CYVSCROLL);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetPosition(Value: Integer);
|
|
begin
|
|
SetParams(Value, FMin, FMax, FPageSize);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetPageSize(Value: Integer);
|
|
begin
|
|
SetParams(FPosition, FMin, FMax, Value);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetMin(Value: Integer);
|
|
begin
|
|
SetParams(FPosition, Value, FMax, FPageSize);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.SetMax(Value: Integer);
|
|
begin
|
|
SetParams(FPosition, FMin, Value, FPageSize);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.Change;
|
|
begin
|
|
inherited Changed;
|
|
if Assigned(FOnChange) then FOnChange(Self);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.Scroll(ScrollCode: TScrollCode; var ScrollPos: Integer);
|
|
begin
|
|
if Assigned(FOnScroll) then FOnScroll(Self, ScrollCode, ScrollPos);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.DoScroll(var Message: TLMScroll);
|
|
var
|
|
ScrollPos: Integer;
|
|
ScrollCode: TScrollCode;
|
|
NewPos: Longint;
|
|
begin
|
|
NewPos := FPosition;
|
|
case Message.ScrollCode of
|
|
SB_LINEUP: begin
|
|
ScrollCode := scLineUp;
|
|
Dec(NewPos, FSmallChange * FRTLFactor);
|
|
end;
|
|
SB_LINEDOWN: begin
|
|
ScrollCode := scLineDown;
|
|
Inc(NewPos, FSmallChange * FRTLFactor);
|
|
end;
|
|
SB_PAGEUP: begin
|
|
ScrollCode := scPageUp;
|
|
Dec(NewPos, FLargeChange * FRTLFactor);
|
|
end;
|
|
SB_PAGEDOWN: begin
|
|
ScrollCode := scPageDown;
|
|
Inc(NewPos, FLargeChange * FRTLFactor);
|
|
end;
|
|
SB_THUMBPOSITION, SB_THUMBTRACK: begin
|
|
if Message.ScrollCode = SB_THUMBPOSITION
|
|
then ScrollCode := scPosition
|
|
else ScrollCode := scTrack;
|
|
{ We need to reverse the positioning because SetPosition below calls
|
|
SetParams that reverses the position. This acts as a double negative. }
|
|
if NotRightToLeft
|
|
then NewPos := Message.Pos
|
|
else NewPos := FMax - Message.Pos;
|
|
end;
|
|
SB_TOP: begin
|
|
ScrollCode := scTop;
|
|
NewPos := FMin;
|
|
end;
|
|
SB_BOTTOM: begin
|
|
ScrollCode := scBottom;
|
|
NewPos := FMax;
|
|
end;
|
|
SB_ENDSCROLL: begin
|
|
ScrollCode := scEndScroll;
|
|
end;
|
|
else
|
|
Exit;
|
|
end;
|
|
|
|
{see issue #20127 +1 follows winapi bug otherwise under mswindows at max position
|
|
we'll have gap between slider and edge of scrollbar. Gtk2 and Qt are fine with this.}
|
|
if NewPos + 1 > (FMax - FPageSize) + 1 then NewPos := (FMax - FPageSize) + 1;
|
|
if NewPos < FMin then NewPos := FMin;
|
|
|
|
ScrollPos := NewPos;
|
|
Scroll(ScrollCode, ScrollPos);
|
|
SetPosition(ScrollPos);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CNHScroll(var Message: TLMHScroll);
|
|
begin
|
|
DoScroll(Message);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CNVScroll(var Message: TLMVScroll);
|
|
begin
|
|
DoScroll(Message);
|
|
end;
|
|
|
|
procedure TCustomScrollBar.CNCtlColorScrollBar(var Message: TLMessage);
|
|
begin
|
|
//CallWIndowProc is not yet created so no code is here
|
|
end;
|
|
|
|
procedure TCustomScrollBar.WMEraseBkgnd(var Message: TLMEraseBkgnd);
|
|
begin
|
|
DefaultHandler(Message);
|
|
end;
|
|
|
|
class procedure TCustomScrollBar.WSRegisterClass;
|
|
begin
|
|
inherited WSRegisterClass;
|
|
RegisterCustomScrollBar;
|
|
end;
|
|
|
|
class function TCustomScrollBar.GetControlClassDefaultSize: TSize;
|
|
begin
|
|
Result.CX := 121;
|
|
Result.CY := GetSystemMetrics(SM_CYHSCROLL);
|
|
end;
|
|
|
|
// included by stdctrls.pp
|