LCL: TControlScrollBar: Visible is not the current state, but a flag to allow the widget to become visible, for Delphi compatibility, fixed calculating Range (the widget frame was added)

git-svn-id: trunk@29031 -
This commit is contained in:
mattias 2011-01-15 12:50:44 +00:00
parent bdde60c6de
commit a6965afecd
5 changed files with 85 additions and 61 deletions

View File

@ -809,8 +809,10 @@ Reads or writes a flag to determine paging increment; default value is 80 pixels
</element> </element>
<!-- property Visibility: published --> <!-- property Visibility: published -->
<element name="TControlScrollBar.Visible"> <element name="TControlScrollBar.Visible">
<short>Is the scroll bar visible?</short> <short>Can the scroll bar be made visible?</short>
<descr>Reads or writes flag to determine visibility, and sets a flag if the property is stored</descr> <descr>Reads or writes flag to determine visibility, and sets a flag if the property is stored.
The Handle object (widget) is made visible if (Visible=true) and (Range&gt;Page).
To get the current visible state of the widget use the method IsScrollBarVisible.</descr>
<seealso/> <seealso/>
</element> </element>
<!-- variable Visibility: private --> <!-- variable Visibility: private -->

View File

@ -86,7 +86,7 @@ type
TControlScrollBar = class(TPersistent) TControlScrollBar = class(TPersistent)
private private
FAutoRange : Longint; FAutoRange : Longint; // = FRange - ClientSize, >=0
FIncrement: TScrollBarInc; FIncrement: TScrollBarInc;
FKind: TScrollBarKind; FKind: TScrollBarKind;
FPage: TScrollBarInc; FPage: TScrollBarInc;
@ -107,7 +107,6 @@ type
function GetRange: Integer; virtual; function GetRange: Integer; virtual;
function GetSize: integer; virtual; function GetSize: integer; virtual;
function GetSmooth: Boolean; virtual; function GetSmooth: Boolean; virtual;
function GetVisible: Boolean; virtual;
function HandleAllocated: boolean; virtual; function HandleAllocated: boolean; virtual;
function IsRangeStored: boolean; virtual; function IsRangeStored: boolean; virtual;
procedure AutoCalcRange; virtual; procedure AutoCalcRange; virtual;
@ -130,10 +129,12 @@ type
{$endif} {$endif}
function GetHorzScrollBar: TControlScrollBar; virtual; function GetHorzScrollBar: TControlScrollBar; virtual;
function GetVertScrollBar: TControlScrollBar; virtual; function GetVertScrollBar: TControlScrollBar; virtual;
protected
function ScrollBarShouldBeVisible: Boolean; virtual; // should the widget be made visible?
public public
constructor Create(AControl: TWinControl; AKind: TScrollBarKind); constructor Create(AControl: TWinControl; AKind: TScrollBarKind);
procedure Assign(Source: TPersistent); override; procedure Assign(Source: TPersistent); override;
function IsScrollBarVisible: Boolean; virtual; function IsScrollBarVisible: Boolean; virtual; // returns current widget state
function ScrollPos: Integer; virtual; function ScrollPos: Integer; virtual;
property Kind: TScrollBarKind read FKind; property Kind: TScrollBarKind read FKind;
function GetOtherScrollBar: TControlScrollBar; function GetOtherScrollBar: TControlScrollBar;
@ -148,7 +149,7 @@ type
property Position: Integer read GetPosition write SetPosition default 0; // 0..Range-Page property Position: Integer read GetPosition write SetPosition default 0; // 0..Range-Page
property Range: Integer read GetRange write SetRange stored IsRangeStored default 0; // >=Page property Range: Integer read GetRange write SetRange stored IsRangeStored default 0; // >=Page
property Tracking: Boolean read FTracking write SetTracking default False; property Tracking: Boolean read FTracking write SetTracking default False;
property Visible: Boolean read GetVisible write SetVisible default True; property Visible: Boolean read FVisible write SetVisible default True;
end; end;
{ TScrollingWinControl } { TScrollingWinControl }
@ -182,7 +183,6 @@ type
constructor Create(TheOwner : TComponent); override; constructor Create(TheOwner : TComponent); override;
destructor Destroy; override; destructor Destroy; override;
procedure UpdateScrollbars; procedure UpdateScrollbars;
function HasVisibleScrollbars: boolean; virtual;
class function GetControlClassDefaultSize: TSize; override; class function GetControlClassDefaultSize: TSize; override;
procedure ScrollBy(DeltaX, DeltaY: Integer); procedure ScrollBy(DeltaX, DeltaY: Integer);
published published
@ -1590,6 +1590,7 @@ function WindowStateToStr(const State: TWindowState): string;
function StrToWindowState(const Name: string): TWindowState; function StrToWindowState(const Name: string): TWindowState;
function dbgs(const State: TWindowState): string; overload; function dbgs(const State: TWindowState): string; overload;
function dbgs(const Action: TCloseAction): string; overload; function dbgs(const Action: TCloseAction): string; overload;
function dbgs(const Kind: TScrollBarKind): string; overload;
type type
TFocusState = Pointer; TFocusState = Pointer;
@ -1772,6 +1773,14 @@ begin
Result:=GetEnumName(TypeInfo(TCloseAction),ord(Action)); Result:=GetEnumName(TypeInfo(TCloseAction),ord(Action));
end; end;
function dbgs(const Kind: TScrollBarKind): string;
begin
if Kind=sbVertical then
Result:='sbVertical'
else
Result:='sbHorizontal';
end;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
function GetParentForm(Control: TControl): TCustomForm; function GetParentForm(Control: TControl): TCustomForm;
begin begin

View File

@ -93,7 +93,7 @@ begin
ScrollInfo.fMask := SIF_POS; ScrollInfo.fMask := SIF_POS;
ScrollInfo.nPos := FPosition; ScrollInfo.nPos := FPosition;
FPosition := SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, FVisible); FPosition := SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, ScrollBarShouldBeVisible);
end; end;
end; end;
@ -110,8 +110,11 @@ begin
begin begin
ScrollInfo.fMask := SIF_PAGE; ScrollInfo.fMask := SIF_PAGE;
GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo); GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
InvalidateScrollInfo; if FPage<>ScrollInfo.nPage then
FPage := ScrollInfo.nPage; begin
FPage := ScrollInfo.nPage;
InvalidateScrollInfo;
end;
end; end;
Result := FPage; Result := FPage;
end; end;
@ -124,8 +127,11 @@ begin
begin begin
ScrollInfo.fMask := SIF_POS; ScrollInfo.fMask := SIF_POS;
GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo); GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
InvalidateScrollInfo; if FPosition<>ScrollInfo.nPos then
FPosition := ScrollInfo.nPos; begin
FPosition := ScrollInfo.nPos;
InvalidateScrollInfo;
end;
end; end;
Result := FPosition; Result := FPosition;
end; end;
@ -133,13 +139,18 @@ end;
function TControlScrollBar.GetRange: Integer; function TControlScrollBar.GetRange: Integer;
var var
ScrollInfo: TScrollInfo; ScrollInfo: TScrollInfo;
NewRange: Integer;
begin begin
if HandleAllocated and (not (FControl is TScrollingWinControl)) then if HandleAllocated and (not (FControl is TScrollingWinControl)) then
begin begin
ScrollInfo.fMask := SIF_Range + SIF_Page; ScrollInfo.fMask := SIF_Range + SIF_Page;
GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo); GetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo);
InvalidateScrollInfo; NewRange := ScrollInfo.nMax - ScrollInfo.nMin;
FRange := ScrollInfo.nMax - ScrollInfo.nMin; if NewRange<>FRange then
begin
FRange:=NewRange;
InvalidateScrollInfo;
end;
end; end;
Result := FRange; Result := FRange;
end; end;
@ -149,16 +160,6 @@ begin
Result := FSmooth; Result := FSmooth;
end; end;
function TControlScrollBar.GetVisible: Boolean;
begin
if HandleAllocated and (not (FControl is TScrollingWinControl)) then
begin
InvalidateScrollInfo;
FVisible := GetScrollbarVisible(Controlhandle, IntfBarKind[Kind]);
end;
Result := FVisible;
end;
procedure TControlScrollBar.SetIncrement(const AValue: TScrollBarInc); procedure TControlScrollBar.SetIncrement(const AValue: TScrollBarInc);
begin begin
// This value is only used by the ScrollHandler procedure // This value is only used by the ScrollHandler procedure
@ -181,10 +182,8 @@ begin
else else
KindID := SM_CXVSCROLL; KindID := SM_CXVSCROLL;
if HandleAllocated then if HandleAllocated then
begin Result := LCLIntf.GetScrollBarSize(ControlHandle,KindID)
Result := LCLIntf.GetScrollBarSize(ControlHandle,KindID); else
InvalidateScrollInfo;
end else
Result := GetSystemMetrics(KindID); Result := GetSystemMetrics(KindID);
end; end;
@ -226,13 +225,18 @@ procedure TControlScrollBar.AutoCalcRange;
end; end;
procedure GetPreferredClientRect(out PreferredWidth, PreferredHeight: integer); procedure GetPreferredClientRect(out PreferredWidth, PreferredHeight: integer);
var
CurClientRect: TRect;
begin begin
PreferredWidth:=0; PreferredWidth:=0;
PreferredHeight:=0; PreferredHeight:=0;
FControl.GetPreferredSize(PreferredWidth,PreferredHeight,true); FControl.GetPreferredSize(PreferredWidth,PreferredHeight,true,false);
//DebugLn(['GetPreferredClientRect ',DbgSName(FControl),' Pref=',PreferredWidth,'x',PreferredHeight]); CurClientRect := FControl.ClientRect;
if PreferredWidth<0 then PreferredWidth:=0; if PreferredWidth>0 then
if PreferredHeight<0 then PreferredHeight:=0; PreferredWidth:=Max(0,PreferredWidth-(FControl.Width-CurClientRect.Right));
if PreferredHeight>0 then
PreferredHeight:=Max(0,PreferredHeight-(FControl.Height-CurClientRect.Bottom));
//DebugLn(['GetPreferredClientRect ',DbgSName(FControl),' PrefClient=',PreferredWidth,'x',PreferredHeight]);
end; end;
procedure AutoCalcVRange; procedure AutoCalcVRange;
@ -252,7 +256,7 @@ procedure TControlScrollBar.AutoCalcRange;
begin begin
GetPreferredClientRect(PreferredWidth,PreferredHeight); GetPreferredClientRect(PreferredWidth,PreferredHeight);
//if FControl.ClassName='TEditorCodetoolsOptionsFrame' then //if FControl.ClassName='TEditorCodetoolsOptionsFrame' then
// DebugLn(['AutoCalcHRange ',DbgSName(FControl),' AutoSize=',FControl.AutoSize,' Bounds=',dbgs(FControl.BoundsRect),' Client=',dbgs(FControl.ClientRect),' pref=',PreferredWidth,'x',PreferredHeight]); //DebugLn(['AutoCalcHRange ',DbgSName(FControl),' AutoSize=',FControl.AutoSize,' Bounds=',dbgs(FControl.BoundsRect),' Client=',dbgs(FControl.ClientRect),' pref=',PreferredWidth,'x',PreferredHeight]);
InternalSetRange(PreferredWidth); InternalSetRange(PreferredWidth);
end; end;
@ -282,21 +286,21 @@ begin
ScrollInfo.nPos := FPosition; ScrollInfo.nPos := FPosition;
ScrollInfo.nPage := FPage; ScrollInfo.nPage := FPage;
ScrollInfo.nTrackPos := FPosition; ScrollInfo.nTrackPos := FPosition;
NewVisible := ScrollBarShouldBeVisible;
if (not FOldScrollInfoValid) or (not CompareMem(@ScrollInfo, @FOldScrollInfo, SizeOf(TScrollInfo))) then if (not FOldScrollInfoValid) or (not CompareMem(@ScrollInfo, @FOldScrollInfo, SizeOf(TScrollInfo))) then
begin begin
FOldScrollInfo := ScrollInfo; FOldScrollInfo := ScrollInfo;
FOldScrollInfoValid := True; FOldScrollInfoValid := True;
SetScrollInfo(FControl.Handle, IntfBarKind[Kind], ScrollInfo, FVisible); SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, NewVisible);
// update policy too // update policy too
ScrollInfo.fMask := SIF_UPDATEPOLICY; ScrollInfo.fMask := SIF_UPDATEPOLICY;
ScrollInfo.nTrackPos := TrackToPolicyMap[FTracking]; ScrollInfo.nTrackPos := TrackToPolicyMap[FTracking];
SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, FVisible); SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, NewVisible);
end; end;
NewVisible := Visible and (ScrollInfo.nMax > ScrollInfo.nPage);
ShowScrollBar(FControl.Handle, IntfBarKind[Kind], NewVisible); ShowScrollBar(FControl.Handle, IntfBarKind[Kind], NewVisible);
{$IFDEF VerboseScrollingWinControl} {$IFDEF VerboseScrollingWinControl}
if DebugCondition then if DebugCondition then
DebugLn(['TControlScrollBar.UpdateScrollBar ',DbgSName(FControl),' ',DbgSName(Self),' FVisible=',FVisible,' Range=',FRange,' FPosition=',FPosition,' FPage=',FPage,' FAutoRange=',FAutoRange]); DebugLn(['TControlScrollBar.UpdateScrollBar ',DbgSName(FControl),' ',DbgSName(Self),' FVisible=',FVisible,' Range=',FRange,' FPosition=',FPosition,' FPage=',FPage,' FAutoRange=',FAutoRange,' ShouldVisible=',NewVisible]);
{$ENDIF} {$ENDIF}
end; end;
@ -399,8 +403,8 @@ begin
Exit; Exit;
FRange := AValue; FRange := AValue;
{$IFDEF VerboseScrollingWinControl} {$IFDEF VerboseScrollingWinControl}
if DebugCondition then //if DebugCondition then
DebugLn(['TControlScrollBar.SetRange ',Self,' fRange=',FRange]); DebugLn(['TControlScrollBar.SetRange ',dbgs(Kind),' ',Self,' fRange=',FRange]);
{$ENDIF} {$ENDIF}
ControlUpdateScrollBars; ControlUpdateScrollBars;
end; end;
@ -427,7 +431,7 @@ begin
ScrollInfo.cbSize := SizeOf(ScrollInfo); ScrollInfo.cbSize := SizeOf(ScrollInfo);
ScrollInfo.fMask := SIF_UPDATEPOLICY; ScrollInfo.fMask := SIF_UPDATEPOLICY;
ScrollInfo.nTrackPos := TrackToPolicyMap[FTracking]; ScrollInfo.nTrackPos := TrackToPolicyMap[FTracking];
SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, FVisible); SetScrollInfo(ControlHandle, IntfBarKind[Kind], ScrollInfo, ScrollBarShouldBeVisible);
end; end;
function TControlScrollBar.ControlHandle: HWnd; function TControlScrollBar.ControlHandle: HWnd;
@ -470,8 +474,9 @@ end;
function TControlScrollBar.IsScrollBarVisible: Boolean; function TControlScrollBar.IsScrollBarVisible: Boolean;
begin begin
Result := (FControl <> nil) and FControl.HandleAllocated and Result:=FVisible;
FControl.IsControlVisible and Visible; if Result and HandleAllocated then
Result := GetScrollbarVisible(ControlHandle, IntfBarKind[Kind]);
end; end;
function TControlScrollBar.ScrollPos: Integer; function TControlScrollBar.ScrollPos: Integer;
@ -501,14 +506,14 @@ end;
function TControlScrollBar.ClientSizeWithBar: integer; function TControlScrollBar.ClientSizeWithBar: integer;
begin begin
Result:=ClientSize; Result:=ClientSize;
if not Visible then if not IsScrollBarVisible then
dec(Result,GetSize); dec(Result,GetSize);
end; end;
function TControlScrollBar.ClientSizeWithoutBar: integer; function TControlScrollBar.ClientSizeWithoutBar: integer;
begin begin
Result:=ClientSize; Result:=ClientSize;
if Visible then if IsScrollBarVisible then
inc(Result,GetSize); inc(Result,GetSize);
end; end;
@ -528,4 +533,9 @@ begin
Result:=nil; Result:=nil;
end; end;
function TControlScrollBar.ScrollBarShouldBeVisible: Boolean;
begin
Result:=FVisible and (FRange>FPage);
end;
// included by forms.pp // included by forms.pp

View File

@ -110,14 +110,15 @@ end;
function TScrollingWinControl.ComputeScrollbars: Boolean; function TScrollingWinControl.ComputeScrollbars: Boolean;
// true if something changed // true if something changed
// update Page, AutoRange, Visible // update Page, AutoRange, IsScrollBarVisible
procedure UpdateRange(p_Bar: TControlScrollBar); function UpdateRange(p_Bar: TControlScrollBar): Boolean;
var var
SBSize: Longint; SBSize: Longint;
OtherScrollbar: TControlScrollBar; OtherScrollbar: TControlScrollBar;
OldAutoRange: LongInt; OldAutoRange: LongInt;
begin begin
Result:=false;
OldAutoRange := p_Bar.FAutoRange; OldAutoRange := p_Bar.FAutoRange;
p_Bar.FAutoRange := 0; p_Bar.FAutoRange := 0;
OtherScrollbar := p_Bar.GetOtherScrollBar; OtherScrollbar := p_Bar.GetOtherScrollBar;
@ -139,7 +140,7 @@ var
begin begin
Result := False; Result := False;
// page (must be smaller than Range and at least 1) // page (must be smaller than Range but at least 1)
NewPage := Max(1,Min(VertScrollbar.ClientSize, High(HorzScrollbar.FPage))); NewPage := Max(1,Min(VertScrollbar.ClientSize, High(HorzScrollbar.FPage)));
if NewPage <> HorzScrollbar.FPage then if NewPage <> HorzScrollbar.FPage then
begin begin
@ -153,8 +154,8 @@ begin
Result := True; Result := True;
end; end;
// range // range
UpdateRange(HorzScrollbar); if UpdateRange(HorzScrollbar) then Result:=true;
UpdateRange(VertScrollbar); if UpdateRange(VertScrollbar) then Result:=true;
end; end;
procedure TScrollingWinControl.UpdateScrollbars; procedure TScrollingWinControl.UpdateScrollbars;
@ -168,7 +169,7 @@ begin
FIsUpdating := True; FIsUpdating := True;
try try
if AutoScroll then if AutoScroll then
ComputeScrollbars; // page, autorange, visible ComputeScrollbars; // page, autorange, IsScrollBarVisible
FVertScrollbar.UpdateScrollbar; FVertScrollbar.UpdateScrollbar;
FHorzScrollbar.UpdateScrollbar; FHorzScrollbar.UpdateScrollbar;
finally finally
@ -176,12 +177,6 @@ begin
end; end;
end; end;
function TScrollingWinControl.HasVisibleScrollbars: boolean;
begin
Result := (VertScrollBar <> nil) and VertScrollBar.Visible and
(HorzScrollBar <> nil) and HorzScrollBar.Visible;
end;
function TScrollingWinControl.StoreScrollBars : Boolean; function TScrollingWinControl.StoreScrollBars : Boolean;
begin begin
Result := not AutoScroll; Result := not AutoScroll;

View File

@ -7899,11 +7899,17 @@ begin
finally finally
Layout.Free; Layout.Free;
end; end;
NewWidth:=0;
NewHeight:=0;
// add the control border around the client area // add the control border around the client area
CurClientRect := GetClientRect; CurClientRect := GetClientRect;
NewWidth:=Width-CurClientRect.Right+NewClientWidth; if (NewClientWidth>0)
NewHeight:=Height-CurClientRect.Bottom+NewClientHeight; or ((NewClientWidth=0) and (csAutoSize0x0 in ControlStyle)) then
NewWidth:=Width-CurClientRect.Right+NewClientWidth;
if (NewClientHeight>0)
or ((NewClientHeight=0) and (csAutoSize0x0 in ControlStyle)) then
NewHeight:=Height-CurClientRect.Bottom+NewClientHeight;
{$IF defined(VerboseAutoSize) or defined(VerboseAllAutoSize)} {$IF defined(VerboseAutoSize) or defined(VerboseAllAutoSize)}
debugln(['TWinControl.CalculatePreferredSize ',DbgSName(Self), debugln(['TWinControl.CalculatePreferredSize ',DbgSName(Self),
' HandleAllocated=',HandleAllocated, ' HandleAllocated=',HandleAllocated,
@ -7915,9 +7921,11 @@ begin
PreferredWidth:=Max(PreferredWidth,NewWidth); PreferredWidth:=Max(PreferredWidth,NewWidth);
PreferredHeight:=Max(PreferredHeight,NewHeight); PreferredHeight:=Max(PreferredHeight,NewHeight);
end; end;
if (PreferredWidth>0) then if (PreferredWidth>0)
or ((PreferredWidth=0) and (csAutoSize0x0 in ControlStyle)) then
inc(PreferredWidth,BorderSpacing.InnerBorder*2); inc(PreferredWidth,BorderSpacing.InnerBorder*2);
if PreferredHeight>0 then if (PreferredHeight>0)
or ((PreferredHeight=0) and (csAutoSize0x0 in ControlStyle)) then
inc(PreferredHeight,BorderSpacing.InnerBorder*2); inc(PreferredHeight,BorderSpacing.InnerBorder*2);
{$IFDEF VerboseAutoSize} {$IFDEF VerboseAutoSize}
debugln('TWinControl.CalculatePreferredSize ',DbgSName(Self), debugln('TWinControl.CalculatePreferredSize ',DbgSName(Self),