From 7a4ede3fa4a9c7d6528320bee1838a8a272fd641 Mon Sep 17 00:00:00 2001 From: zeljan1 Date: Tue, 4 Mar 2025 09:55:10 +0100 Subject: [PATCH] Gtk3: proper resize of LCLGtkFixed inside SrollingWindow, also mouse offset is needed to make LCL happy. --- lcl/interfaces/gtk3/gtk3widgets.pas | 58 ++++++++++++++++++++++++++--- lcl/interfaces/gtk3/gtk3winapi.inc | 10 +++++ 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/lcl/interfaces/gtk3/gtk3widgets.pas b/lcl/interfaces/gtk3/gtk3widgets.pas index 643362e8c4..9f574b24e4 100644 --- a/lcl/interfaces/gtk3/gtk3widgets.pas +++ b/lcl/interfaces/gtk3/gtk3widgets.pas @@ -863,6 +863,9 @@ type { TGtk3ScrollingWinControl } TGtk3ScrollingWinControl = class(TGtk3CustomControl) + strict private + class procedure ScrollingWinControlFixedSizeAllocate(AWidget: PGtkWidget; + AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static; protected function CreateWidget(const {%H-}Params: TCreateParams):PGtkWidget; override; end; @@ -1795,7 +1798,7 @@ begin MousePos.x := X; MousePos.y := Y; end; - + OffsetMousePos(@MousePos); Msg.XPos := SmallInt(MousePos.X); Msg.YPos := SmallInt(MousePos.Y); @@ -1819,7 +1822,7 @@ var AStruct: TPaintStruct; AClipRect: TGdkRectangle; localClip:TRect; - P: TPoint; + //P: TPoint; AScrolledWin: PGtkScrolledWindow; ACaret: TGtk3Caret; {$IFDEF GTK3DEBUGDESIGNER} @@ -1875,7 +1878,7 @@ begin try try - P := getClientOffset; + //P := getClientOffset; //cairo_translate(AContext, P.X, P.Y); DoBeforeLCLPaint; LCLObject.WindowProc(TLMessage(Msg)); @@ -1981,6 +1984,7 @@ begin MousePos.x := Round(Event^.scroll.x); MousePos.y := Round(Event^.scroll.y); end; + OffsetMousePos(@MousePos); Msg.X := MousePos.X; Msg.Y := MousePos.Y; @@ -2322,6 +2326,7 @@ begin MousePos.x := Round(Event^.button.x); MousePos.y := Round(Event^.button.y); end; + OffsetMousePos(@MousePos); Msg.XPos := SmallInt(MousePos.X); Msg.YPos := SmallInt(MousePos.Y); @@ -9152,18 +9157,54 @@ end; { TGtk3ScrollingWinControl } +class procedure TGtk3ScrollingWinControl.ScrollingWinControlFixedSizeAllocate(AWidget: PGtkWidget; + AGdkRect: PGdkRectangle; Data: gpointer); cdecl; +var + hadj, vadj: PGtkAdjustment; + HSize,VSize: Integer; +begin + //writeln('GtkFixed size-allocate x=',AGdkRect^.x,' Y=',AGdkRect^.y,' Width=',AGdkRect^.width,' H=',AGdkRect^.height,' VAdj ? ',Assigned(TGtk3CustomControl(Data).LCLVAdj)); + VSize := 0; + HSize := 0; + hadj := TGtk3CustomControl(Data).GetScrolledWindow^.get_hadjustment; + vadj := TGtk3CustomControl(Data).GetScrolledWindow^.get_vadjustment; + + if Assigned(TGtk3CustomControl(Data).LCLVAdj) and Gtk3IsAdjustment(vadj) then + with TGtk3CustomControl(Data).LCLVAdj^ do + VSize := Round(upper - value - page_size); + + if Assigned(TGtk3CustomControl(Data).LCLHAdj) and Gtk3IsAdjustment(hadj) then + with TGtk3CustomControl(Data).LCLHAdj^ do + HSize := Round(upper - value - page_size); + + PGtkFixed(Awidget)^.set_size_request(AGdkRect^.width + HSize, AGdkRect^.height + VSize); + + {TODO: eg treeview editor, if scrollbar value > 0 then editor resets position to 0, + to fix this we must position editor at y pos - adjustment.value} + if Assigned(TGtk3CustomControl(Data).LCLVAdj) and Gtk3IsAdjustment(vadj) then + with TGtk3CustomControl(Data).LCLVAdj^ do + vadj^.configure({vadj^.}value, lower, upper, step_increment, page_increment, page_size); + + if Assigned(TGtk3CustomControl(Data).LCLHAdj) and Gtk3IsAdjustment(hadj) then + with TGtk3CustomControl(Data).LCLHAdj^ do + hadj^.configure({hadj^.}value, lower, upper, step_increment, page_increment, page_size); + + if TGtk3CustomControl(Data).LCLObject.ClientRectNeedsInterfaceUpdate then + TGtk3CustomControl(Data).LCLObject.DoAdjustClientRectChange; + +end; + function TGtk3ScrollingWinControl.CreateWidget(const Params: TCreateParams ): PGtkWidget; begin FHasPaint := True; FWidgetType := [wtWidget, wtContainer, wtScrollingWin, wtScrollingWinControl]; Result := PGtkScrolledWindow(TGtkScrolledWindow.new(nil, nil)); - FCentralWidget := TGtkFixed.new; + FCentralWidget := LCLGtkFixedNew; FCentralWidget^.set_has_window(True); FCentralWidget^.show; PGtkScrolledWindow(Result)^.add_with_viewport(FCentralWidget); - // PGtkScrolledWindow(Result)^.add(FCentralWidget); PGtkViewport(PGtkScrolledWindow(Result)^.get_child)^.set_shadow_type(BorderStyleShadowMap[bsNone]); PGtkScrolledWindow(Result)^.set_shadow_type(BorderStyleShadowMap[TScrollingWinControl(LCLObject).BorderStyle]); @@ -9175,6 +9216,13 @@ begin PGtkScrolledWindow(Result)^.set_can_focus(False); FCentralWidget^.set_can_focus(True); + g_signal_connect_data(FCentralWidget,'size-allocate',TGCallback(@ScrollingWinControlFixedSizeAllocate), Self, nil, G_CONNECT_DEFAULT); + + with PGtkScrolledWindow(Result)^.get_vadjustment^ do + LCLVAdj := gtk_adjustment_new(value, lower, upper, step_increment, page_increment, page_size); + with PGtkScrolledWindow(Result)^.get_hadjustment^ do + LCLHAdj := gtk_adjustment_new(value, lower, upper, step_increment, page_increment, page_size); + end; { TGtk3Window } diff --git a/lcl/interfaces/gtk3/gtk3winapi.inc b/lcl/interfaces/gtk3/gtk3winapi.inc index f7589b4690..c9d8cbcb91 100644 --- a/lcl/interfaces/gtk3/gtk3winapi.inc +++ b/lcl/interfaces/gtk3/gtk3winapi.inc @@ -3992,6 +3992,16 @@ var ATarget := Adjustment^.upper; SetGDouble(ATarget, ScrollInfo.nMax, HasChanged); Adjustment^.upper := ATarget ; + + if (AControl is TGtk3ScrollingWinControl) and (wtContainer in AControl.WidgetType) then + begin + //hah + if SbStyle = SB_VERT then + TGtk3ScrollingWinControl(AControl).GetContainerWidget^.set_size_request(TGtk3ScrollingWinControl(AControl).GetContainerWidget^.get_allocated_width, Round(ATarget) + 1) + else + if SBStyle = SB_HORZ then + TGtk3ScrollingWinControl(AControl).GetContainerWidget^.set_size_request(Round(ATarget) + 1, TGtk3ScrollingWinControl(AControl).GetContainerWidget^.get_allocated_height); + end; end; if (ScrollInfo.FMask and SIF_PAGE) <> 0 then