View Issue Details

IDProjectCategoryView StatusLast Update
0021918LazarusLCLpublic2017-03-10 12:42
ReporterAlexander Koblov Assigned ToOndrej Pokorny  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version1.1 (SVN) 
Summary0021918: StringGrid scroll up on each height decrease/increase
DescriptionStringGrid scroll up when height decreased and increased after.
Steps To ReproduceRun attached example program and press button some times. On each second push StringGrid will scroll up.
TagsNo tags attached.
Fixed in Revision54379
LazTarget-
Widgetset
Attached Files

Relationships

related to 0031475 closedOndrej Pokorny TCustomGrid: wrong TopRow / extra calls to OnTopLeftChange 

Activities

2012-05-02 12:47

 

grid_bug.zip (129,164 bytes)

accorp

2017-03-03 19:43

reporter  

grid-fix-scroll.diff (1,858 bytes)   
Index: lcl/grids.pas
===================================================================
--- lcl/grids.pas	(revision 54338)
+++ lcl/grids.pas	(working copy)
@@ -6782,29 +6782,34 @@
 
 procedure TCustomGrid.DoOnChangeBounds;
 var
-  PrevSpace: Integer;
-  NewTopLeft, AvailSpace: TPoint;
+  NewTopLeft: TPoint;
+  PrevSpace, AvailSpace: Integer;
 begin
   inherited DoOnChangeBounds;
 
   FGridFlags := FGridFlags + [gfUpdatingSize];
-
-  AVailSpace.x := ClientWidth - FGCache.MaxClientXY.x;
-  AVailSpace.y := ClientHeight - FGCache.MaxClientXY.y;
   NewTopLeft := FTopLeft;
 
-  while (AvailSpace.x>0) and (NewTopLeft.x>FixedCols) do begin
-    PrevSpace := GetColWidths(NewTopLeft.x-1);
-    if AvailSpace.x>(PrevSpace-FGCache.TLColOff) then
-      Dec(NewTopLeft.x, 1);
-    Dec(AvailSpace.x, PrevSpace);
+  if ColCount>0 then begin
+    ColRowToOffset(True, True, ColCount-1, PrevSpace, AvailSpace);
+    AvailSpace := ClientWidth - AvailSpace - 1;
+    while (AvailSpace>0) and (NewTopLeft.x>FixedCols) do begin
+      PrevSpace := GetColWidths(NewTopLeft.x-1);
+      if AvailSpace>(PrevSpace-FGCache.TLColOff) then
+        Dec(NewTopLeft.x, 1);
+      Dec(AvailSpace, PrevSpace);
+    end;
   end;
 
-  while (AvailSpace.y>0) and (NewTopLeft.y>FixedRows) do begin
-    PrevSpace := GetRowHeights(NewTopLeft.y-1);
-    if AvailSpace.y>PrevSpace then
-      Dec(NewTopLeft.y, 1);
-    Dec(AvailSpace.y, PrevSpace);
+  if RowCount>0 then begin
+    ColRowToOffset(False, True, RowCount-1, PrevSpace, AvailSpace);
+    AvailSpace := ClientHeight - AvailSpace - 1;
+    while (AvailSpace>0) and (NewTopLeft.y>FixedRows) do begin
+      PrevSpace := GetRowHeights(NewTopLeft.y-1);
+      if AvailSpace>PrevSpace then
+        Dec(NewTopLeft.y, 1);
+      Dec(AvailSpace, PrevSpace);
+    end;
   end;
 
   if not PointIgual(FTopleft,NewTopLeft) then begin
grid-fix-scroll.diff (1,858 bytes)   

accorp

2017-03-10 09:35

reporter  

lcl-grid-fix-scroll-smooth.diff (3,150 bytes)   
Index: lcl/grids.pas
===================================================================
--- lcl/grids.pas	(revision 54378)
+++ lcl/grids.pas	(working copy)
@@ -6782,38 +6782,69 @@
 
 procedure TCustomGrid.DoOnChangeBounds;
 var
-  PrevSpace: Integer;
-  NewTopLeft, AvailSpace: TPoint;
+  NewTopLeft, NewTLOff: TPoint;
+  StartPos, EndPos, AvailSpace, PrevSpace: Integer;
 begin
   inherited DoOnChangeBounds;
 
   FGridFlags := FGridFlags + [gfUpdatingSize];
-
-  AVailSpace.x := ClientWidth - FGCache.MaxClientXY.x;
-  AVailSpace.y := ClientHeight - FGCache.MaxClientXY.y;
   NewTopLeft := FTopLeft;
+  NewTLOff.x := FGCache.TLColOff;
+  NewTLOff.y := FGCache.TLRowOff;
 
-  while (AvailSpace.x>0) and (NewTopLeft.x>FixedCols) do begin
-    PrevSpace := GetColWidths(NewTopLeft.x-1);
-    if AvailSpace.x>(PrevSpace-FGCache.TLColOff) then
-      Dec(NewTopLeft.x, 1);
-    Dec(AvailSpace.x, PrevSpace);
+  if ColCount > 0 then begin
+    ColRowToOffset(True, True, ColCount-1, StartPos, EndPos);
+    AvailSpace := ClientWidth - EndPos;
+    if AvailSpace > 0 then begin
+      while NewTopLeft.x > FixedCols do begin
+        PrevSpace := GetColWidths(NewTopLeft.x-1);
+        if AvailSpace >= PrevSpace then
+          Dec(NewTopLeft.x, 1)
+        else
+          Break;
+        Dec(AvailSpace, PrevSpace);
+      end;
+      if goSmoothScroll in Options then begin
+        Dec(AvailSpace, NewTLOff.x);
+        if (AvailSpace > 0) and (NewTopLeft.x > FixedCols) then begin
+          Dec(NewTopLeft.x, 1);
+          Dec(AvailSpace, GetColWidths(NewTopLeft.x));
+        end;
+        NewTLOff.x := Max(0, -AvailSpace);
+      end;
+    end;
   end;
 
-  while (AvailSpace.y>0) and (NewTopLeft.y>FixedRows) do begin
-    PrevSpace := GetRowHeights(NewTopLeft.y-1);
-    if AvailSpace.y>PrevSpace then
-      Dec(NewTopLeft.y, 1);
-    Dec(AvailSpace.y, PrevSpace);
+  if RowCount > 0 then begin
+    ColRowToOffset(False, True, RowCount-1, StartPos, EndPos);
+    AvailSpace := ClientHeight - EndPos;
+    if AvailSpace > 0 then begin
+      while NewTopLeft.y > FixedRows do begin
+        PrevSpace := GetRowHeights(NewTopLeft.y-1);
+        if AvailSpace >= PrevSpace then
+          Dec(NewTopLeft.y, 1)
+        else
+          Break;
+        Dec(AvailSpace, PrevSpace);
+      end;
+      if goSmoothScroll in Options then begin
+        Dec(AvailSpace, NewTLOff.y);
+        if (AvailSpace > 0) and (NewTopLeft.y > FixedRows) then begin
+          Dec(NewTopLeft.y, 1);
+          Dec(AvailSpace, GetRowHeights(NewTopLeft.y));
+        end;
+        NewTLOff.y := Max(0, -AvailSpace);
+      end;
+    end;
   end;
 
-  if not PointIgual(FTopleft,NewTopLeft) then begin
+  if (not PointIgual(FTopleft,NewTopLeft))
+    or (FGCache.TLColOff <> NewTLOff.x)
+    or (FGCache.TLRowOff <> NewTLOff.y)
+  then begin
     FTopLeft := NewTopleft;
-    FGCache.TLColOff := 0;
-    FGCache.TLRowOff := 0;
-    if goSmoothScroll in options then begin
-      // TODO: adjust new TLColOff and TLRowOff
-    end;
+    FGCache.TLColOff := NewTLOff.x;
+    FGCache.TLRowOff := NewTLOff.y;
     DoTopLeftChange(True);
   end else
     VisualChange;

accorp

2017-03-10 09:35

reporter   ~0098787

Please ignore previous patch, new one adds smooth scrolling on grid resize.

Ondrej Pokorny

2017-03-10 11:47

developer   ~0098791

Thanks for the patch - it solves this issue but doesn't solve the smooth resizing issue from 0031475.

Ondrej Pokorny

2017-03-10 11:59

developer   ~0098792

Furthermore your patch opens 0031475 again - it sends unnecessary OnTopLeftChange during smooth scrolling.

accorp

2017-03-10 12:02

reporter   ~0098793

Main problem with smooth resize is that FTopRow is wrongly changing inside UpdateCachedSizes. But removing it brings back 0030211 I do not know how to solve.

accorp

2017-03-10 12:16

reporter  

lcl-grid-fix-scroll-smooth2.diff (2,880 bytes)   
Index: lcl/grids.pas
===================================================================
--- lcl/grids.pas	(revision 54378)
+++ lcl/grids.pas	(working copy)
@@ -6782,38 +6782,62 @@
 
 procedure TCustomGrid.DoOnChangeBounds;
 var
-  PrevSpace: Integer;
-  NewTopLeft, AvailSpace: TPoint;
+  NewTopLeft: TPoint;
+  StartPos, EndPos, AvailSpace, PrevSpace: Integer;
 begin
   inherited DoOnChangeBounds;
 
   FGridFlags := FGridFlags + [gfUpdatingSize];
-
-  AVailSpace.x := ClientWidth - FGCache.MaxClientXY.x;
-  AVailSpace.y := ClientHeight - FGCache.MaxClientXY.y;
   NewTopLeft := FTopLeft;
 
-  while (AvailSpace.x>0) and (NewTopLeft.x>FixedCols) do begin
-    PrevSpace := GetColWidths(NewTopLeft.x-1);
-    if AvailSpace.x>(PrevSpace-FGCache.TLColOff) then
-      Dec(NewTopLeft.x, 1);
-    Dec(AvailSpace.x, PrevSpace);
+  if ColCount > 0 then begin
+    ColRowToOffset(True, True, ColCount-1, StartPos, EndPos);
+    AvailSpace := ClientWidth - EndPos;
+    if AvailSpace > 0 then begin
+      while NewTopLeft.x > FixedCols do begin
+        PrevSpace := GetColWidths(NewTopLeft.x-1);
+        if AvailSpace >= PrevSpace then
+          Dec(NewTopLeft.x, 1)
+        else
+          Break;
+        Dec(AvailSpace, PrevSpace);
+      end;
+      if goSmoothScroll in Options then begin
+        Dec(AvailSpace, FGCache.TLColOff);
+        if (AvailSpace > 0) and (NewTopLeft.x > FixedCols) then begin
+          Dec(NewTopLeft.x, 1);
+          Dec(AvailSpace, GetColWidths(NewTopLeft.x));
+        end;
+        FGCache.TLColOff := Max(0, -AvailSpace);
+      end;
+    end;
   end;
 
-  while (AvailSpace.y>0) and (NewTopLeft.y>FixedRows) do begin
-    PrevSpace := GetRowHeights(NewTopLeft.y-1);
-    if AvailSpace.y>PrevSpace then
-      Dec(NewTopLeft.y, 1);
-    Dec(AvailSpace.y, PrevSpace);
+  if RowCount > 0 then begin
+    ColRowToOffset(False, True, RowCount-1, StartPos, EndPos);
+    AvailSpace := ClientHeight - EndPos;
+    if AvailSpace > 0 then begin
+      while NewTopLeft.y > FixedRows do begin
+        PrevSpace := GetRowHeights(NewTopLeft.y-1);
+        if AvailSpace >= PrevSpace then
+          Dec(NewTopLeft.y, 1)
+        else
+          Break;
+        Dec(AvailSpace, PrevSpace);
+      end;
+      if goSmoothScroll in Options then begin
+        Dec(AvailSpace, FGCache.TLRowOff);
+        if (AvailSpace > 0) and (NewTopLeft.y > FixedRows) then begin
+          Dec(NewTopLeft.y, 1);
+          Dec(AvailSpace, GetRowHeights(NewTopLeft.y));
+        end;
+        FGCache.TLRowOff := Max(0, -AvailSpace);
+      end;
+    end;
   end;
 
   if not PointIgual(FTopleft,NewTopLeft) then begin
     FTopLeft := NewTopleft;
-    FGCache.TLColOff := 0;
-    FGCache.TLRowOff := 0;
-    if goSmoothScroll in options then begin
-      // TODO: adjust new TLColOff and TLRowOff
-    end;
     DoTopLeftChange(True);
   end else
     VisualChange;

Ondrej Pokorny

2017-03-10 12:28

developer   ~0098794

> Main problem with smooth resize is that FTopRow is wrongly changing inside UpdateCachedSizes.

FTopRow is changing correctly. Only the smooth offset was ignored. Fixed in r54380.

> I do not know how to solve.

Never say that to your customer or employer :)

accorp

2017-03-10 12:31

reporter   ~0098795

@Ondrej Pokorny
You broke stringgrid :) Scroll to bottom line and resize.

Ondrej Pokorny

2017-03-10 12:42

developer   ~0098796

> You broke stringgrid :) Scroll to bottom line and resize.

I don't see a problem. Please report separately with a test application.

Issue History

Date Modified Username Field Change
2012-05-02 12:47 Alexander Koblov New Issue
2012-05-02 12:47 Alexander Koblov File Added: grid_bug.zip
2012-05-03 19:19 Jesus Reyes Status new => assigned
2012-05-03 19:19 Jesus Reyes Assigned To => Jesus Reyes
2017-03-03 19:43 accorp File Added: grid-fix-scroll.diff
2017-03-10 09:35 accorp File Added: lcl-grid-fix-scroll-smooth.diff
2017-03-10 09:35 accorp Note Added: 0098787
2017-03-10 11:31 Ondrej Pokorny Assigned To Jesus Reyes => Ondrej Pokorny
2017-03-10 11:46 Ondrej Pokorny Relationship added related to 0031475
2017-03-10 11:47 Ondrej Pokorny Note Added: 0098791
2017-03-10 11:59 Ondrej Pokorny Note Added: 0098792
2017-03-10 12:02 accorp Note Added: 0098793
2017-03-10 12:16 accorp File Added: lcl-grid-fix-scroll-smooth2.diff
2017-03-10 12:23 Ondrej Pokorny Fixed in Revision => 54379
2017-03-10 12:23 Ondrej Pokorny LazTarget => -
2017-03-10 12:23 Ondrej Pokorny Status assigned => resolved
2017-03-10 12:23 Ondrej Pokorny Resolution open => fixed
2017-03-10 12:28 Ondrej Pokorny Note Added: 0098794
2017-03-10 12:31 accorp Note Added: 0098795
2017-03-10 12:42 Ondrej Pokorny Note Added: 0098796