From 7e3817c7c039d8554a1782703c6b5dddd381c4d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=BDeljan=20Rikalo?= Date: Sun, 9 Mar 2025 19:44:15 +0100 Subject: [PATCH] Qt5,Qt6: fixed designing on scrolled forms. issue #41517 (cherry picked from commit 9de7888945429a00bb60259286d545a3d85ab6d6) Co-authored-by: zeljan1 --- lcl/interfaces/qt5/qtlclintf.inc | 4 ++++ lcl/interfaces/qt5/qtwidgets.pas | 23 ++++++++++++++++++----- lcl/interfaces/qt5/qtwinapi.inc | 20 +++++++++++++++++--- lcl/interfaces/qt6/qtlclintf.inc | 4 ++++ lcl/interfaces/qt6/qtwidgets.pas | 23 ++++++++++++++++++----- lcl/interfaces/qt6/qtwinapi.inc | 20 +++++++++++++++++--- 6 files changed, 78 insertions(+), 16 deletions(-) diff --git a/lcl/interfaces/qt5/qtlclintf.inc b/lcl/interfaces/qt5/qtlclintf.inc index 0b9cc5c0cd..53f092c296 100644 --- a/lcl/interfaces/qt5/qtlclintf.inc +++ b/lcl/interfaces/qt5/qtlclintf.inc @@ -290,11 +290,15 @@ var QtDC: TQtDeviceContext absolute DC; X, Y: Integer; W, H: Integer; + P: TPoint; begin if not IsValidDC(DC) then exit; QtDC.save; try + P := Point(0, 0); + SetWindowOrgEx(DC, 0, 0, @P); + W := (R.Right - R.Left - 1) div DX; H := (R.Bottom - R.Top - 1) div DY; diff --git a/lcl/interfaces/qt5/qtwidgets.pas b/lcl/interfaces/qt5/qtwidgets.pas index b1b45b34c1..f218d077c2 100644 --- a/lcl/interfaces/qt5/qtwidgets.pas +++ b/lcl/interfaces/qt5/qtwidgets.pas @@ -20186,8 +20186,15 @@ begin Msg.PaintStruct^.hdc := FDesignContext; P := getClientOffset; + + {$IFDEF QTSCROLLABLEFORMS} + inc(P.X, -ScrollArea.horizontalScrollBar.getValue); + inc(P.Y, -ScrollArea.verticalScrollBar.getValue); + {$ELSE} inc(P.X, FScrollX); inc(P.Y, FScrollY); + {$ENDIF} + TQtDeviceContext(Msg.DC).translate(P.X, P.Y); // send paint message @@ -20229,9 +20236,13 @@ var begin if FDesignControl = nil then Exit; - // FDesignControl must be same as form area, - // since we use QWidget, not QMainWindow in design time. + {$IFDEF QTSCROLLABLEFORMS} + QWidget_contentsRect(ScrollArea.viewportWidget, @R); + R.Width := R.Width + ScrollArea.horizontalScrollBar.getMax; + R.Height := R.Height + ScrollArea.verticalScrollBar.getMax; + {$ELSE} QWidget_contentsRect(Widget, @R); + {$ENDIF} with R do begin QWidget_move(FDesignControl, Left, Top); @@ -20381,9 +20392,7 @@ begin {$IFDEF QTSCROLLABLEFORMS} else if (aWidget is TQtWindowArea) then - begin TQtWindowArea(aWidget).scroll(XStep, YStep); - end; {$ENDIF} end else begin @@ -20469,7 +20478,11 @@ begin end; end; end; - QEventPaint: SlotDesignControlPaint(Sender, Event); + QEventPaint: + begin + SlotDesignControlPaint(Sender, Event); + Result := True; + end; QEventContextMenu: SlotContextMenu(Sender, Event); end; finally diff --git a/lcl/interfaces/qt5/qtwinapi.inc b/lcl/interfaces/qt5/qtwinapi.inc index 697badd362..8dc9a79c92 100644 --- a/lcl/interfaces/qt5/qtwinapi.inc +++ b/lcl/interfaces/qt5/qtwinapi.inc @@ -2820,7 +2820,8 @@ function TQtWidgetSet.GetDCOriginRelativeToWindow(PaintDC: HDC; var QtDC: TQtDeviceContext absolute PaintDC; Matrix: QTransformH; - P: TPoint; + DCScreenOrigin, P: TPoint; + Pt1, Pt2: TQtPoint; begin {$ifdef VerboseQtWinAPI} WriteLn('[WinAPI GetDCOriginRelativeToWindow] PaintDC ' + dbghex(PaintDC)); @@ -2831,13 +2832,26 @@ begin Matrix := QPainter_transform(QtDC.Widget); OriginDiff := Point(0, 0); P := Point(0, 0); + DCScreenOrigin := Point(0, 0); + if (QtDC.Parent <> nil) then + begin + Pt2.X := 0; + Pt2.y := 0; + QWidget_mapToGlobal(QtDC.Parent, @Pt1, @Pt2); + DCScreenOrigin.X := Pt1.X; + DCScreenOrigin.Y := Pt1.Y; + end; if WindowHandle <> 0 then + begin P := TQtWidget(WindowHandle).getClientOffset; + P := TQtWidget(WindowHandle).MapToGlobal(P, False); + end; if Matrix <> nil then begin - OriginDiff.X := Round(QTransform_Dx(Matrix)) - P.X; - OriginDiff.Y := Round(QTransform_Dy(Matrix)) - P.Y; + OriginDiff.X := DCScreenOrigin.X - P.X; + OriginDiff.Y := DCScreenOrigin.Y - P.Y; end; + Result := True; end; {------------------------------------------------------------------------------ diff --git a/lcl/interfaces/qt6/qtlclintf.inc b/lcl/interfaces/qt6/qtlclintf.inc index f029776598..212e34c05a 100644 --- a/lcl/interfaces/qt6/qtlclintf.inc +++ b/lcl/interfaces/qt6/qtlclintf.inc @@ -290,11 +290,15 @@ var QtDC: TQtDeviceContext absolute DC; X, Y: Integer; W, H: Integer; + P: TPoint; begin if not IsValidDC(DC) then exit; QtDC.save; try + P := Point(0, 0); + SetWindowOrgEx(DC, 0, 0, @P); + W := (R.Right - R.Left - 1) div DX; H := (R.Bottom - R.Top - 1) div DY; diff --git a/lcl/interfaces/qt6/qtwidgets.pas b/lcl/interfaces/qt6/qtwidgets.pas index b3cdaca68a..a5d7f76cf0 100644 --- a/lcl/interfaces/qt6/qtwidgets.pas +++ b/lcl/interfaces/qt6/qtwidgets.pas @@ -20107,8 +20107,15 @@ begin Msg.PaintStruct^.hdc := FDesignContext; P := getClientOffset; + + {$IFDEF QTSCROLLABLEFORMS} + inc(P.X, -ScrollArea.horizontalScrollBar.getValue); + inc(P.Y, -ScrollArea.verticalScrollBar.getValue); + {$ELSE} inc(P.X, FScrollX); inc(P.Y, FScrollY); + {$ENDIF} + TQtDeviceContext(Msg.DC).translate(P.X, P.Y); // send paint message @@ -20150,9 +20157,13 @@ var begin if FDesignControl = nil then Exit; - // FDesignControl must be same as form area, - // since we use QWidget, not QMainWindow in design time. + {$IFDEF QTSCROLLABLEFORMS} + QWidget_contentsRect(ScrollArea.viewportWidget, @R); + R.Width := R.Width + ScrollArea.horizontalScrollBar.getMax; + R.Height := R.Height + ScrollArea.verticalScrollBar.getMax; + {$ELSE} QWidget_contentsRect(Widget, @R); + {$ENDIF} with R do begin QWidget_move(FDesignControl, Left, Top); @@ -20302,9 +20313,7 @@ begin {$IFDEF QTSCROLLABLEFORMS} else if (aWidget is TQtWindowArea) then - begin TQtWindowArea(aWidget).scroll(XStep, YStep); - end; {$ENDIF} end else begin @@ -20390,7 +20399,11 @@ begin end; end; end; - QEventPaint: SlotDesignControlPaint(Sender, Event); + QEventPaint: + begin + SlotDesignControlPaint(Sender, Event); + Result := True; + end; QEventContextMenu: SlotContextMenu(Sender, Event); end; finally diff --git a/lcl/interfaces/qt6/qtwinapi.inc b/lcl/interfaces/qt6/qtwinapi.inc index 3c7662b9be..4fd85c846e 100644 --- a/lcl/interfaces/qt6/qtwinapi.inc +++ b/lcl/interfaces/qt6/qtwinapi.inc @@ -2817,7 +2817,8 @@ function TQtWidgetSet.GetDCOriginRelativeToWindow(PaintDC: HDC; var QtDC: TQtDeviceContext absolute PaintDC; Matrix: QTransformH; - P: TPoint; + DCScreenOrigin, P: TPoint; + Pt1, Pt2: TQtPoint; begin {$ifdef VerboseQtWinAPI} WriteLn('[WinAPI GetDCOriginRelativeToWindow] PaintDC ' + dbghex(PaintDC)); @@ -2828,13 +2829,26 @@ begin Matrix := QPainter_transform(QtDC.Widget); OriginDiff := Point(0, 0); P := Point(0, 0); + DCScreenOrigin := Point(0, 0); + if (QtDC.Parent <> nil) then + begin + Pt2.X := 0; + Pt2.y := 0; + QWidget_mapToGlobal(QtDC.Parent, @Pt1, @Pt2); + DCScreenOrigin.X := Pt1.X; + DCScreenOrigin.Y := Pt1.Y; + end; if WindowHandle <> 0 then + begin P := TQtWidget(WindowHandle).getClientOffset; + P := TQtWidget(WindowHandle).MapToGlobal(P, False); + end; if Matrix <> nil then begin - OriginDiff.X := Round(QTransform_Dx(Matrix)) - P.X; - OriginDiff.Y := Round(QTransform_Dy(Matrix)) - P.Y; + OriginDiff.X := DCScreenOrigin.X - P.X; + OriginDiff.Y := DCScreenOrigin.Y - P.Y; end; + Result := True; end; {------------------------------------------------------------------------------