marge r50991 #b61461e71a,r50994,r51003:

LCL: fixed infinite loop and crash with TScrollingWinControl. issue #29194
LCL: add support of scrolling invisible window. issue #29194
Qt: keep track of scrolled offset when viewport is not visible. issue #29239

git-svn-id: branches/fixes_1_6@51007 -
This commit is contained in:
ondrej 2015-12-23 13:12:36 +00:00
parent aa802ffa10
commit 02da6304e8
4 changed files with 34 additions and 4 deletions

View File

@ -73,6 +73,7 @@ begin
PrevPosition := FPosition; PrevPosition := FPosition;
// position has to be set before FControl.ScrollBy !!! // position has to be set before FControl.ScrollBy !!!
FPosition := Value; FPosition := Value;
// scroll logical client area of FControl // scroll logical client area of FControl
if Kind = sbVertical then if Kind = sbVertical then
FControl.ScrollBy(0, PrevPosition - FPosition) FControl.ScrollBy(0, PrevPosition - FPosition)

View File

@ -6136,10 +6136,10 @@ end;
procedure TWinControl.ScrollBy_WS(DeltaX, DeltaY: Integer); procedure TWinControl.ScrollBy_WS(DeltaX, DeltaY: Integer);
begin begin
if HandleAllocated and IsWindowVisible(Handle) then if HandleAllocated then
TWSWinControlClass(WidgetSetClass).ScrollBy(Self, DeltaX, DeltaY) TWSWinControlClass(WidgetSetClass).ScrollBy(Self, DeltaX, DeltaY)
else else
ScrollBy(DeltaX, DeltaY); raise Exception.Create('TWinControl.ScrollBy_WS: Handle not allocated');
end; end;
procedure TWinControl.ScrollBy(DeltaX, DeltaY: Integer); procedure TWinControl.ScrollBy(DeltaX, DeltaY: Integer);

View File

@ -473,9 +473,14 @@ type
{ TQtViewPort } { TQtViewPort }
TQtViewPort = class(TQtWidget) TQtViewPort = class(TQtWidget)
private
{when our viewport is invisible then we must keep track of scrolling. issue #29239}
FInvisibleX: integer;
FInvisibleY: integer;
public public
function CanPaintBackground: Boolean; override; function CanPaintBackground: Boolean; override;
function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override; function EventFilter(Sender: QObjectH; Event: QEventH): Boolean; cdecl; override;
procedure InitializeWidget; override;
procedure scroll(dx, dy: integer; ARect: PRect = nil); override; procedure scroll(dx, dy: integer; ARect: PRect = nil); override;
procedure stackUnder(AWidget: QWidgetH); override; procedure stackUnder(AWidget: QWidgetH); override;
end; end;
@ -16085,6 +16090,18 @@ begin
' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate); ' Event=', EventTypeToStr(Event),' inUpdate=',inUpdate);
{$endif} {$endif}
case QEvent_type(Event) of case QEvent_type(Event) of
QEventShow,
QEventShowToParent:
begin
{Qt does not track scrolled offset of widget when it''s not visible.issue #29239}
if (FInvisibleX <> 0) or (FInvisibleY <> 0) then
begin
QWidget_scroll(Widget, FInvisibleX, FInvisibleY);
FInvisibleX := 0;
FInvisibleY := 0;
end;
Result := inherited EventFilter(Sender, Event);
end;
QEventResize: QEventResize:
begin begin
// immediate update clientRect ! // immediate update clientRect !
@ -16167,9 +16184,21 @@ begin
end; end;
end; end;
procedure TQtViewPort.InitializeWidget;
begin
FInvisibleX := 0;
FInvisibleY := 0;
inherited InitializeWidget;
end;
procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil); procedure TQtViewPort.scroll(dx, dy: integer; ARect: PRect = nil);
begin begin
inherited scroll(dx, dy, ARect); if not getVisible then
begin
FInvisibleX += dx;
FInvisibleY += dy;
end else
inherited scroll(dx, dy, ARect);
FScrollX := FScrollX + dx; FScrollX := FScrollX + dx;
FScrollY := FScrollY + dy; FScrollY := FScrollY + dy;
end; end;

View File

@ -590,7 +590,7 @@ end;
class procedure TWin32WSWinControl.ScrollBy(const AWinControl: TWinControl; class procedure TWin32WSWinControl.ScrollBy(const AWinControl: TWinControl;
DeltaX, DeltaY: integer); DeltaX, DeltaY: integer);
begin begin
if Windows.IsWindowVisible(AWinControl.Handle) then if AWinControl.HandleAllocated then
ScrollWindowEx(AWinControl.Handle, DeltaX, DeltaY, nil, nil, 0, nil, SW_INVALIDATE or SW_ERASE or SW_SCROLLCHILDREN); ScrollWindowEx(AWinControl.Handle, DeltaX, DeltaY, nil, nil, 0, nil, SW_INVALIDATE or SW_ERASE or SW_SCROLLCHILDREN);
end; end;