View Issue Details

IDProjectCategoryView StatusLast Update
0034418LazarusWidgetsetpublic2019-08-22 22:32
ReporterChris RordenAssigned ToJuha Manninen 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionreopened 
PlatformSystem76 OryxOSUbuntu / PopOSOS Version18.04
Product Version1.9 (SVN)Product Buildsvn 59296 
Target VersionFixed in Version 
Summary0034418: GTK2 autosize incorrect for TTrackBar if TickStyle := tsNone
DescriptionWith GTK, the autosizing height always assumes that the TrackBar is set to the default TickStyle := tsAuto. The sizing is wrong if one uses TickStyle := tsNone. Inlcuded demo program illustrates the issue, the patch fixes the issue.

With the demo program, you can revert some Trackbars back to tsAuto to demonstrate that the old behavior is retained correctly for any trackbars with tsAuto.
Steps To ReproducePlace a couple trackbars on a form, set each to TickStyle := tsNone, set anchoring so they should be packed one on top of the other. Run the program, note the wide space between trackbars.
TagsNo tags attached.
Fixed in Revisionr61473, r61676
LazTarget-
WidgetsetGTK 2
Attached Files
  • myPatch.diff (1,073 bytes)
    Index: lcl/interfaces/gtk2/gtk2lclintf.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2lclintf.inc	(revision 59294)
    +++ lcl/interfaces/gtk2/gtk2lclintf.inc	(working copy)
    @@ -768,6 +768,9 @@
       Updates the constraints object (e.g. TSizeConstraints) with interface specific
       bounds.
      ------------------------------------------------------------------------------}
    +
    +
    +
     function TGtk2WidgetSet.GetControlConstraints(Constraints: TObject): boolean;
     var
       SizeConstraints: TSizeConstraints absolute Constraints;
    @@ -826,6 +829,10 @@
           if TCustomTrackBar(SizeConstraints.Control).Orientation=trHorizontal then
           begin
             Widget:=GetStyleWidget(lgsHScale);
    +        if ((SizeConstraints.Control as TCustomTrackBar).TickStyle = tsNone) then begin
    +           gtk_scale_set_draw_value(GTK_SCALE(Widget), false);
    +           gtk_widget_size_request(Widget,@Widget^.requisition);
    +        end;
             MinHeight:=Widget^.requisition.height;
           end else begin
             Widget:=GetStyleWidget(lgsVScale);
    
    myPatch.diff (1,073 bytes)
  • gtkTrackBarHeight.zip (130,419 bytes)
  • gtkTrackBarHeight.png (25,443 bytes)
    gtkTrackBarHeight.png (25,443 bytes)
  • gtk2TrackBarHeight2.zip (4,648 bytes)
  • gtk2TrackBarHeight3.zip (4,895 bytes)
  • ttrackbar-tickstyle-constraints.patch (4,736 bytes)
    --- lcl/include/trackbar.inc
    +++ lcl/include/trackbar.inc
    @@ -70,6 +70,7 @@
       TabStop := True;
       with GetControlClassDefaultSize do
         SetInitialBounds(0, 0, CX, CY);
    +  AutoSize := True;
     end;
     
     {------------------------------------------------------------------------------
    @@ -125,6 +126,7 @@
         begin
           OldWidth:=Width;
           OldHeight:=Height;
    +      Constraints.UpdateInterfaceConstraints;
           SetBounds(Left,Top,OldHeight,OldWidth);
           if HandleAllocated then
             TWSTrackBarClass(WidgetSetClass).SetOrientation(Self, FOrientation);
    @@ -237,6 +239,10 @@
       begin
         FTickStyle := Value;
         ApplyChanges;
    +    Constraints.UpdateInterfaceConstraints;
    +    DoAutoSize;
    +    if HandleAllocated then
    +      TWSTrackBarClass(WidgetSetClass).SetTickStyle(Self, FTickStyle);
       end;
     end;
     
    --- lcl/interfaces/gtk2/gtk2lclintf.inc
    +++ lcl/interfaces/gtk2/gtk2lclintf.inc
    @@ -826,9 +826,15 @@
           if TCustomTrackBar(SizeConstraints.Control).Orientation=trHorizontal then
           begin
             Widget:=GetStyleWidget(lgsHScale);
    +        gtk_scale_set_draw_value(PGtkScale(Widget),
    +                                 TCustomTrackBar(SizeConstraints.Control).TickStyle <> tsNone);
    +        gtk_widget_size_request(Widget, @Widget^.Requisition);
             MinHeight:=Widget^.requisition.height;
           end else begin
             Widget:=GetStyleWidget(lgsVScale);
    +        gtk_scale_set_draw_value(PGtkScale(Widget),
    +                                 TCustomTrackBar(SizeConstraints.Control).TickStyle <> tsNone);
    +        gtk_widget_size_request(Widget, @Widget^.Requisition);
             MinWidth:=Widget^.requisition.width;
           end;
           //DebugLn(['TGtk2WidgetSet.GetControlConstraints ',DbgSName(SizeConstraints.Control),' ',MinWidth,',',MinHeight]);
    --- lcl/interfaces/gtk2/gtk2wscomctrls.pp
    +++ lcl/interfaces/gtk2/gtk2wscomctrls.pp
    @@ -264,6 +264,9 @@
         class function  GetPosition(const ATrackBar: TCustomTrackBar): integer; override;
         class procedure SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer); override;
         class procedure SetOrientation(const ATrackBar: TCustomTrackBar; const {%H-}AOrientation: TTrackBarOrientation); override;
    +    class procedure GetPreferredSize(const {%H-}AWinControl: TWinControl;
    +                        var {%H-}PreferredWidth, PreferredHeight: integer;
    +                        {%H-}WithThemeSpace: Boolean); override;
       end;
     
       { TGtk2WSCustomTreeView }
    @@ -443,6 +446,29 @@
       end;
     end;
     
    +class procedure TGtk2WSTrackBar.GetPreferredSize(
    +  const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer;
    +  WithThemeSpace: Boolean);
    +var
    +  TrackBarWidget: PGtkWidget;
    +  Requisition: TGtkRequisition;
    +begin
    +  if TCustomTrackBar(AWinControl).Orientation = trHorizontal then
    +    TrackBarWidget := GetStyleWidget(lgsHScale)
    +  else
    +    TrackBarWidget := GetStyleWidget(lgsVScale);
    +  // set size to default
    +  gtk_scale_set_draw_value(PGtkScale(TrackBarWidget),
    +                           TCustomTrackBar(AWinControl).TickStyle <> tsNone);
    +  gtk_widget_set_size_request(TrackBarWidget, -1, -1);
    +  // ask default size
    +  gtk_widget_size_request(TrackBarWidget, @Requisition);
    +  if TCustomTrackBar(AWinControl).Orientation = trHorizontal then
    +    PreferredHeight := Requisition.height
    +  else
    +    PreferredWidth := Requisition.width;
    +end;
    +
     { TGtk2WSProgressBar }
     
     class procedure TGtk2WSProgressBar.UpdateProgressBarText(const AProgressBar: TCustomProgressBar);
    --- lcl/widgetset/wscomctrls.pp
    +++ lcl/widgetset/wscomctrls.pp
    @@ -230,6 +230,7 @@
         class procedure SetOrientation(const ATrackBar: TCustomTrackBar; const AOrientation: TTrackBarOrientation); virtual;
         class procedure SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer); virtual;
         class procedure SetTick(const ATrackBar: TCustomTrackBar; const ATick: integer); virtual;
    +    class procedure SetTickStyle(const ATrackBar: TCustomTrackBar; const ATickStyle: TTickStyle); virtual;
       end;
       TWSTrackBarClass = class of TWSTrackBar;
     
    @@ -781,6 +782,11 @@
     begin
     end;
     
    +class procedure TWSTrackBar.SetTickStyle(const ATrackBar: TCustomTrackBar; const ATickStyle: TTickStyle);
    +begin
    +  RecreateWnd(ATrackBar);
    +end;
    +
     { WidgetSetRegistration }
     
     procedure RegisterStatusBar;
    --- lcl/comctrls.pp
    +++ lcl/comctrls.pp
    @@ -2715,6 +2715,7 @@
         constructor Create(AOwner: TComponent); override;
         procedure SetTick(Value: Integer);
       published
    +    property AutoSize default true;
         property Frequency: Integer read FFrequency write SetFrequency default 1;
         property LineSize: Integer read FLineSize write SetLineSize default 1;
         property Max: Integer read FMax write SetMax default 10;
    
    

Relationships

related to 0035763 closedDmitry Boyarintsev SVN 61473 regression: autosize error 
related to 0035861 closedJuha Manninen GTK2: TTrackBar does not AutoSize for hi-dpi 

Activities

Chris Rorden

2018-10-14 17:35

reporter  

myPatch.diff (1,073 bytes)
Index: lcl/interfaces/gtk2/gtk2lclintf.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2lclintf.inc	(revision 59294)
+++ lcl/interfaces/gtk2/gtk2lclintf.inc	(working copy)
@@ -768,6 +768,9 @@
   Updates the constraints object (e.g. TSizeConstraints) with interface specific
   bounds.
  ------------------------------------------------------------------------------}
+
+
+
 function TGtk2WidgetSet.GetControlConstraints(Constraints: TObject): boolean;
 var
   SizeConstraints: TSizeConstraints absolute Constraints;
@@ -826,6 +829,10 @@
       if TCustomTrackBar(SizeConstraints.Control).Orientation=trHorizontal then
       begin
         Widget:=GetStyleWidget(lgsHScale);
+        if ((SizeConstraints.Control as TCustomTrackBar).TickStyle = tsNone) then begin
+           gtk_scale_set_draw_value(GTK_SCALE(Widget), false);
+           gtk_widget_size_request(Widget,@Widget^.requisition);
+        end;
         MinHeight:=Widget^.requisition.height;
       end else begin
         Widget:=GetStyleWidget(lgsVScale);
myPatch.diff (1,073 bytes)

Chris Rorden

2018-10-14 17:36

reporter  

gtkTrackBarHeight.zip (130,419 bytes)

Chris Rorden

2018-10-14 17:36

reporter  

gtkTrackBarHeight.png (25,443 bytes)
gtkTrackBarHeight.png (25,443 bytes)

Chris Rorden

2018-10-18 13:45

reporter  

gtk2TrackBarHeight2.zip (4,648 bytes)

Chris Rorden

2018-10-18 13:49

reporter   ~0111449

I have added a new sample project that shows one unintended consequence of my suggested patch: the size of the widget seems to be deteremined when the program launches, so if a widget is changed between tsAuto and tsNone at run time the new size is not reflected by the widget. So my patch works as long as the widget style is not changed at run time.

The web page
 http://wiki.lazarus.freepascal.org/Autosize_/_Layout
 suggests we can start/execute a new AutoSize, but this does not seem to help here. Is there a way that we can force the GTK2 autosize to be recomputed when the tsStyle is changed at run time?

Zeljan Rikalo

2018-10-18 18:28

developer   ~0111455

Isn't there SetStyle() or similar in widgetset code for TTrackBar ? If not then RecreateWnd() should fix the problem.

Chris Rorden

2018-10-18 19:34

reporter  

gtk2TrackBarHeight3.zip (4,895 bytes)

Chris Rorden

2018-10-18 19:36

reporter   ~0111456

Zeljan
  See attached demo - RecreateWnd does not help. I also think the QT spacing could be improved. Maybe I am unusual in using these widgets this way. These issues influence most of my projects.

Joeny Ang

2019-04-13 13:56

reporter  

ttrackbar-tickstyle-constraints.patch (4,736 bytes)
--- lcl/include/trackbar.inc
+++ lcl/include/trackbar.inc
@@ -70,6 +70,7 @@
   TabStop := True;
   with GetControlClassDefaultSize do
     SetInitialBounds(0, 0, CX, CY);
+  AutoSize := True;
 end;
 
 {------------------------------------------------------------------------------
@@ -125,6 +126,7 @@
     begin
       OldWidth:=Width;
       OldHeight:=Height;
+      Constraints.UpdateInterfaceConstraints;
       SetBounds(Left,Top,OldHeight,OldWidth);
       if HandleAllocated then
         TWSTrackBarClass(WidgetSetClass).SetOrientation(Self, FOrientation);
@@ -237,6 +239,10 @@
   begin
     FTickStyle := Value;
     ApplyChanges;
+    Constraints.UpdateInterfaceConstraints;
+    DoAutoSize;
+    if HandleAllocated then
+      TWSTrackBarClass(WidgetSetClass).SetTickStyle(Self, FTickStyle);
   end;
 end;
 
--- lcl/interfaces/gtk2/gtk2lclintf.inc
+++ lcl/interfaces/gtk2/gtk2lclintf.inc
@@ -826,9 +826,15 @@
       if TCustomTrackBar(SizeConstraints.Control).Orientation=trHorizontal then
       begin
         Widget:=GetStyleWidget(lgsHScale);
+        gtk_scale_set_draw_value(PGtkScale(Widget),
+                                 TCustomTrackBar(SizeConstraints.Control).TickStyle <> tsNone);
+        gtk_widget_size_request(Widget, @Widget^.Requisition);
         MinHeight:=Widget^.requisition.height;
       end else begin
         Widget:=GetStyleWidget(lgsVScale);
+        gtk_scale_set_draw_value(PGtkScale(Widget),
+                                 TCustomTrackBar(SizeConstraints.Control).TickStyle <> tsNone);
+        gtk_widget_size_request(Widget, @Widget^.Requisition);
         MinWidth:=Widget^.requisition.width;
       end;
       //DebugLn(['TGtk2WidgetSet.GetControlConstraints ',DbgSName(SizeConstraints.Control),' ',MinWidth,',',MinHeight]);
--- lcl/interfaces/gtk2/gtk2wscomctrls.pp
+++ lcl/interfaces/gtk2/gtk2wscomctrls.pp
@@ -264,6 +264,9 @@
     class function  GetPosition(const ATrackBar: TCustomTrackBar): integer; override;
     class procedure SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer); override;
     class procedure SetOrientation(const ATrackBar: TCustomTrackBar; const {%H-}AOrientation: TTrackBarOrientation); override;
+    class procedure GetPreferredSize(const {%H-}AWinControl: TWinControl;
+                        var {%H-}PreferredWidth, PreferredHeight: integer;
+                        {%H-}WithThemeSpace: Boolean); override;
   end;
 
   { TGtk2WSCustomTreeView }
@@ -443,6 +446,29 @@
   end;
 end;
 
+class procedure TGtk2WSTrackBar.GetPreferredSize(
+  const AWinControl: TWinControl; var PreferredWidth, PreferredHeight: integer;
+  WithThemeSpace: Boolean);
+var
+  TrackBarWidget: PGtkWidget;
+  Requisition: TGtkRequisition;
+begin
+  if TCustomTrackBar(AWinControl).Orientation = trHorizontal then
+    TrackBarWidget := GetStyleWidget(lgsHScale)
+  else
+    TrackBarWidget := GetStyleWidget(lgsVScale);
+  // set size to default
+  gtk_scale_set_draw_value(PGtkScale(TrackBarWidget),
+                           TCustomTrackBar(AWinControl).TickStyle <> tsNone);
+  gtk_widget_set_size_request(TrackBarWidget, -1, -1);
+  // ask default size
+  gtk_widget_size_request(TrackBarWidget, @Requisition);
+  if TCustomTrackBar(AWinControl).Orientation = trHorizontal then
+    PreferredHeight := Requisition.height
+  else
+    PreferredWidth := Requisition.width;
+end;
+
 { TGtk2WSProgressBar }
 
 class procedure TGtk2WSProgressBar.UpdateProgressBarText(const AProgressBar: TCustomProgressBar);
--- lcl/widgetset/wscomctrls.pp
+++ lcl/widgetset/wscomctrls.pp
@@ -230,6 +230,7 @@
     class procedure SetOrientation(const ATrackBar: TCustomTrackBar; const AOrientation: TTrackBarOrientation); virtual;
     class procedure SetPosition(const ATrackBar: TCustomTrackBar; const NewPosition: integer); virtual;
     class procedure SetTick(const ATrackBar: TCustomTrackBar; const ATick: integer); virtual;
+    class procedure SetTickStyle(const ATrackBar: TCustomTrackBar; const ATickStyle: TTickStyle); virtual;
   end;
   TWSTrackBarClass = class of TWSTrackBar;
 
@@ -781,6 +782,11 @@
 begin
 end;
 
+class procedure TWSTrackBar.SetTickStyle(const ATrackBar: TCustomTrackBar; const ATickStyle: TTickStyle);
+begin
+  RecreateWnd(ATrackBar);
+end;
+
 { WidgetSetRegistration }
 
 procedure RegisterStatusBar;
--- lcl/comctrls.pp
+++ lcl/comctrls.pp
@@ -2715,6 +2715,7 @@
     constructor Create(AOwner: TComponent); override;
     procedure SetTick(Value: Integer);
   published
+    property AutoSize default true;
     property Frequency: Integer read FFrequency write SetFrequency default 1;
     property LineSize: Integer read FLineSize write SetLineSize default 1;
     property Max: Integer read FMax write SetMax default 10;

Joeny Ang

2019-04-13 13:57

reporter   ~0115472

Hi, maybe this will help.

Patch: ttrackbar-tickstyle-constraints.patch

Things changed:
1. published AutoSize property
2. call Constraints.UpdateInterfaceConstraints when Orientation or TickStyle is changed
3. added procedure TWSTrackBar.SetTickStyle(), this will call RecreateWnd()
4. added procedure TGtk2WSTrackBar.GetPreferredSize(), called by autosize
5. modified your patch (myPatch.diff) to include vertical orientation

BTW, I'm primarily on Gnome/GTK2, not tested on other widgetsets.

Cheers!

Juha Manninen

2019-06-25 07:47

developer   ~0116912

Last edited: 2019-06-25 15:48

View 2 revisions

Applied the last patch, thanks.

Was the patch made against Lazarus trunk? One hunk applied with suspiciously big offset (53 lines). Please check that everything is OK.

$ patch -p0 < ~/patch/ttrackbar-tickstyle-constraints.patch
patching file lcl/include/trackbar.inc
patching file lcl/interfaces/gtk2/gtk2lclintf.inc
patching file lcl/interfaces/gtk2/gtk2wscomctrls.pp
patching file lcl/widgetset/wscomctrls.pp
Hunk 0000001 succeeded at 239 (offset 9 lines).
Hunk 0000002 succeeded at 835 (offset 53 lines).
patching file lcl/comctrls.pp
Hunk 0000001 succeeded at 2721 (offset 6 lines).

Joeny Ang

2019-06-29 03:17

reporter   ~0117003

Hi Juha,

Thanks for applying the patch. I think all's good. The patch was created against release v2.0.0, hence the offsets in one of the files.

Cheers.

Juha Manninen

2019-08-01 22:12

developer   ~0117538

Last edited: 2019-08-01 23:35

View 2 revisions

Other developers pointed an error with the applied patch.
It sets AutoSize true by default and breaks compatibility with previous revisions of LFM where autoSize is false.
I guess it must be kept false.
The AutoSize logic for TrackBar should be changed so that only height is affected. It can be done in CalculatePreferredSize by leaving PreferredWidth to 0.

How is this done in Delphi VCL?

Joeny Ang

2019-08-02 04:33

reporter   ~0117539

Last Delphi I used was Delphi 3. :D But according to online docs, the AutoSize property of TTrackBar is private. For compatibility, let's just set the default to False.

The AutoSize logic is as you said: only height is affected on horizontal trackbars; width on vertical trackbars.

Juha Manninen

2019-08-09 21:20

developer   ~0117617

AutoSize=True was reverted in r61676.
Please check.

Issue History

Date Modified Username Field Change
2018-10-14 17:35 Chris Rorden New Issue
2018-10-14 17:35 Chris Rorden File Added: myPatch.diff
2018-10-14 17:36 Chris Rorden File Added: gtkTrackBarHeight.zip
2018-10-14 17:36 Chris Rorden File Added: gtkTrackBarHeight.png
2018-10-18 13:45 Chris Rorden File Added: gtk2TrackBarHeight2.zip
2018-10-18 13:49 Chris Rorden Note Added: 0111449
2018-10-18 18:28 Zeljan Rikalo Note Added: 0111455
2018-10-18 19:34 Chris Rorden File Added: gtk2TrackBarHeight3.zip
2018-10-18 19:36 Chris Rorden Note Added: 0111456
2019-04-13 13:56 Joeny Ang File Added: ttrackbar-tickstyle-constraints.patch
2019-04-13 13:57 Joeny Ang Note Added: 0115472
2019-06-25 07:17 Juha Manninen Assigned To => Juha Manninen
2019-06-25 07:17 Juha Manninen Status new => assigned
2019-06-25 07:47 Juha Manninen Status assigned => resolved
2019-06-25 07:47 Juha Manninen Resolution open => fixed
2019-06-25 07:47 Juha Manninen Fixed in Revision => r61473
2019-06-25 07:47 Juha Manninen LazTarget => -
2019-06-25 07:47 Juha Manninen Widgetset GTK 2 => GTK 2
2019-06-25 07:47 Juha Manninen Note Added: 0116912
2019-06-25 15:16 Juha Manninen Relationship added related to 0035763
2019-06-25 15:48 Juha Manninen Note Edited: 0116912 View Revisions
2019-06-29 03:17 Joeny Ang Note Added: 0117003
2019-07-02 13:17 Chris Rorden Status resolved => closed
2019-08-01 21:26 Juha Manninen Relationship added related to 0035861
2019-08-01 22:12 Juha Manninen Status closed => assigned
2019-08-01 22:12 Juha Manninen Resolution fixed => reopened
2019-08-01 22:12 Juha Manninen Note Added: 0117538
2019-08-01 23:35 Juha Manninen Note Edited: 0117538 View Revisions
2019-08-02 04:33 Joeny Ang Note Added: 0117539
2019-08-09 21:20 Juha Manninen Status assigned => resolved
2019-08-09 21:20 Juha Manninen Fixed in Revision r61473 => r61473, r61676
2019-08-09 21:20 Juha Manninen Widgetset GTK 2 => GTK 2
2019-08-09 21:20 Juha Manninen Note Added: 0117617
2019-08-22 22:32 Chris Rorden Status resolved => closed