From ccda0b17c43bc9e8f8f2682ef2861b21f91ae5c2 Mon Sep 17 00:00:00 2001 From: zeljan1 Date: Sun, 9 Mar 2025 18:14:59 +0100 Subject: [PATCH] Gtk3: renamed CustomControlLayoutSizeAllocate to ScrolledLayoutSizeAllocate, moved to TGtk3ScrollableWin class so can be reused later by TGtk3Window. --- lcl/interfaces/gtk3/gtk3widgets.pas | 76 ++++++++++++++--------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/lcl/interfaces/gtk3/gtk3widgets.pas b/lcl/interfaces/gtk3/gtk3widgets.pas index ae0f94e9f3..5d2d42e9fc 100644 --- a/lcl/interfaces/gtk3/gtk3widgets.pas +++ b/lcl/interfaces/gtk3/gtk3widgets.pas @@ -528,6 +528,9 @@ type procedure SetHScrollBarPolicy(AValue: TGtkPolicyType); virtual; procedure SetVScrollBarPolicy(AValue: TGtkPolicyType); virtual; protected + class procedure ScrolledLayoutSizeAllocate(AWidget: PGtkWidget; + AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static; {very important, see note inside method} + class function RangeChangeValue(ARange: PGtkRange; AScrollType: TGtkScrollType; AValue: gdouble; AData: TGtk3Widget): gboolean; cdecl; static; class procedure RangeValueChanged(range: PGtkRange; data: gpointer); cdecl; static; @@ -841,9 +844,6 @@ type { TGtk3CustomControl } TGtk3CustomControl = class(TGtk3ScrollableWin) - strict private - class procedure CustomControlLayoutSizeAllocate(AWidget: PGtkWidget; - AGdkRect: PGdkRectangle; Data: gpointer); cdecl; static; {very important, see note inside method} protected function CreateWidget(const {%H-}Params: TCreateParams):PGtkWidget; override; function EatArrowKeys(const {%H-}AKey: Word): Boolean; override; @@ -5708,6 +5708,40 @@ begin AScrollWin^.set_policy(APolicyH, AValue); end; +class procedure TGtk3ScrollableWin.ScrolledLayoutSizeAllocate( + AWidget: PGtkWidget; AGdkRect: PGdkRectangle; Data: gpointer); cdecl; +var + hadj, vadj: PGtkAdjustment; + //aWindow: PGdkWindow; + //aCtl: TGtk3Widget absolute Data; + HSize,VSize: integer; + uWidth, uHeight: guint; +begin + {Note: Gtk expects that we set content size and then it calculates scrollbar values. LCL + is doing opposite, it sets scrollbar values eg via SetScrollInfo and then content should + be automatically calculated by widgetset. Gtk is crazy about it. + So, we are in charge here to help both. We save adjusted values + in setscrollinfo in LCLVAdj and LCLHAdj, so after GtkLayout sends size-allocate with accurate + content size we apply LCL values to adjustments and everybody is happy. + TODO: eg TTreeView editor, if scrollbar position is not at lower pos, showing + editor moves scrollbar to pos 0, if we apply LCL saved value here, then + editor won't show at all. Maybe moving editor and showing should take into + account scrollbar position and calculate x,y offset.} + + hadj := PGtkScrollable(aWidget)^.get_hadjustment; + vadj := PGtkScrollable(aWidget)^.get_vadjustment; + + HSize := Max(AGdkRect^.Width, Round(hAdj^.upper)); + VSize := Max(AGdkRect^.Height, Round(vAdj^.upper)); + + PGtkLayout(aWidget)^.get_size(@uWidth, @uHeight); + if (uWidth <> HSize) or (uHeight <> VSize) then + PGtkLayout(aWidget)^.set_size(HSize, VSize); + + if TGtk3Widget(Data).LCLObject.ClientRectNeedsInterfaceUpdate then + TGtk3Widget(Data).LCLObject.DoAdjustClientRectChange; +end; + procedure ApplyNoHoverCss(Widget: PGtkWidget); var CssProvider: PGtkCssProvider; @@ -8718,40 +8752,6 @@ end; { TGtk3CustomControl } -class procedure TGtk3CustomControl.CustomControlLayoutSizeAllocate(AWidget: PGtkWidget; - AGdkRect: PGdkRectangle; Data: gpointer); cdecl; -var - hadj, vadj: PGtkAdjustment; - //aWindow: PGdkWindow; - //aCtl: TGtk3Widget absolute Data; - HSize,VSize: integer; - uWidth, uHeight: guint; -begin - {Note: Gtk expects that we set content size and then it calculates scrollbar values. LCL - is doing opposite, it sets scrollbar values eg via SetScrollInfo and then content should - be automatically calculated by widgetset. Gtk is crazy about it. - So, we are in charge here to help both. We save adjusted values - in setscrollinfo in LCLVAdj and LCLHAdj, so after GtkLayout sends size-allocate with accurate - content size we apply LCL values to adjustments and everybody is happy. - TODO: eg TTreeView editor, if scrollbar position is not at lower pos, showing - editor moves scrollbar to pos 0, if we apply LCL saved value here, then - editor won't show at all. Maybe moving editor and showing should take into - account scrollbar position and calculate x,y offset.} - - hadj := PGtkScrollable(aWidget)^.get_hadjustment; - vadj := PGtkScrollable(aWidget)^.get_vadjustment; - - HSize := Max(AGdkRect^.Width, Round(hAdj^.upper)); - VSize := Max(AGdkRect^.Height, Round(vAdj^.upper)); - - PGtkLayout(aWidget)^.get_size(@uWidth, @uHeight); - if (uWidth <> HSize) or (uHeight <> VSize) then - PGtkLayout(aWidget)^.set_size(HSize, VSize); - - if TGtk3CustomControl(Data).LCLObject.ClientRectNeedsInterfaceUpdate then - TGtk3CustomControl(Data).LCLObject.DoAdjustClientRectChange; -end; - function TGtk3CustomControl.CreateWidget(const Params: TCreateParams): PGtkWidget; begin FHasPaint := True; @@ -8779,7 +8779,7 @@ begin g_object_set(PGObject(FCentralWidget), 'resize-mode', [GTK_RESIZE_QUEUE, nil]); gtk_layout_set_size(PGtkLayout(FCentralWidget), 1, 1); - g_signal_connect_data(FCentralWidget,'size-allocate',TGCallback(@CustomControlLayoutSizeAllocate), Self, nil, G_CONNECT_DEFAULT); + g_signal_connect_data(FCentralWidget,'size-allocate',TGCallback(@ScrolledLayoutSizeAllocate), Self, nil, G_CONNECT_DEFAULT); with PGtkScrolledWindow(Result)^.get_vadjustment^ do LCLVAdj := gtk_adjustment_new(value, lower, upper, step_increment, page_increment, page_size);