From 5add9ce41cfd1cc8ea1298f83502bbeb67dbbadf Mon Sep 17 00:00:00 2001 From: Joachim Marder Date: Sat, 20 Jan 2024 15:37:57 +0100 Subject: [PATCH] Fix for issue #1228:Columns EndUpdate and duplicate position --- Source/VirtualTrees.Header.pas | 53 +++++++++++++++++----------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/Source/VirtualTrees.Header.pas b/Source/VirtualTrees.Header.pas index 78991bfd..641190b8 100644 --- a/Source/VirtualTrees.Header.pas +++ b/Source/VirtualTrees.Header.pas @@ -452,6 +452,7 @@ implementation WinApi.UxTheme, System.Math, System.SysUtils, + System.Generics.Defaults, Vcl.Forms, VirtualTrees.HeaderPopup, VirtualTrees.BaseTree, @@ -4397,38 +4398,36 @@ procedure TVirtualTreeColumns.DrawButtonText(DC : HDC; Caption : string; Bounds //---------------------------------------------------------------------------------------------------------------------- procedure TVirtualTreeColumns.FixPositions; - // Fixes column positions after loading from DFM or Bidi mode change. - var - I : Integer; - LoopAgain: Boolean; + LColumnsByPos: TList; + I: Integer; begin - // Fix positions that too large, see #1179 - // Fix duplicate positions, see #1228 - repeat - LoopAgain := False; - for I := 0 to Count - 1 do + LColumnsByPos := TList.Create; + try + LColumnsByPos.Capacity := Self.Count; + for I := 0 to Self.Count-1 do + LColumnsByPos.Add(Items[I]); + + LColumnsByPos.Sort( + TComparer.Construct( + function(const A, B: TVirtualTreeColumn): Integer + begin + Result := CompareValue(A.Position, B.Position); + if Result = 0 then + Result := CompareValue(A.Index, B.Index); + end) + ); + + for I := 0 to LColumnsByPos.Count-1 do begin - if Integer(Items[I].FPosition) >= Count then - begin - Items[I].Position := Count -1; - LoopAgain := True; - end; - if (i < Count -1) and (Items[I].Position = Items[I+1].FPosition) then - begin - if Items[I].FPosition > 0 then - Dec(Items[I].FPosition) - else - Inc(Items[I].FPosition); - LoopAgain := True; - end; - end; // for - until not LoopAgain; + LColumnsByPos[I].FPosition := I; + Self.FPositionToIndex[I] := LColumnsByPos[I].Index; + end; - // Update position array - for I := 0 to Count - 1 do - FPositionToIndex[Items[I].Position] := I; + finally + LColumnsByPos.Free; + end; FNeedPositionsFix := False; UpdatePositions(True);