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>
<!-- property Visibility: published -->
<element name="TControlScrollBar.Visible">
<short>Is the scroll bar visible?</short>
<descr>Reads or writes flag to determine visibility, and sets a flag if the property is stored</descr>
<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.
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/>
</element>
<!-- variable Visibility: private -->

View File

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

View File

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

View File

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

View File

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