mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-22 14:39:13 +02:00
LCL: grids: Implements MinSize/MaxSize column properties for grids with AutofillColumns=true, issue #34548
This commit is contained in:
parent
06a60b60b6
commit
7b9589dc61
138
lcl/grids.pas
138
lcl/grids.pas
@ -75,6 +75,9 @@ const
|
|||||||
DEFCOLWIDTH = 64;
|
DEFCOLWIDTH = 64;
|
||||||
DEFBUTTONWIDTH = 25;
|
DEFBUTTONWIDTH = 25;
|
||||||
DEFIMAGEPADDING = 2;
|
DEFIMAGEPADDING = 2;
|
||||||
|
DEFMINSIZE = 0;
|
||||||
|
DEFMAXSIZE = 0;
|
||||||
|
DEFSIZEPRIORITY = 1;
|
||||||
|
|
||||||
type
|
type
|
||||||
EGridException = class(Exception);
|
EGridException = class(Exception);
|
||||||
@ -2271,12 +2274,11 @@ procedure TCustomGrid.InternalAutoFillColumns;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
I, ForcedIndex: Integer;
|
i, availableSize, avgSize, rest: Integer;
|
||||||
Count: Integer;
|
widths: array of record
|
||||||
aPriority, aMin, aMax: Integer;
|
aIndex, aMin, aMax, aPriority, aWidth: Integer;
|
||||||
AvailableSize: Integer;
|
end;
|
||||||
TotalWidth: Integer; // total grid's width
|
done, isMax, isMin: boolean;
|
||||||
FixedSizeWidth: Integer; // total width of Fixed Sized Columns
|
|
||||||
begin
|
begin
|
||||||
if not AutoFillColumns then
|
if not AutoFillColumns then
|
||||||
exit;
|
exit;
|
||||||
@ -2290,66 +2292,73 @@ begin
|
|||||||
// when InternalAutoFillColumns is called from DoChangeBounds
|
// when InternalAutoFillColumns is called from DoChangeBounds
|
||||||
// for example.
|
// for example.
|
||||||
|
|
||||||
// Insert the algorithm that modify ColWidths accordingly
|
// A simple algorithm is implemented:
|
||||||
//
|
|
||||||
// For testing purposes, a simple algortihm is implemented:
|
|
||||||
// if SizePriority=0, column size should be unmodified
|
// if SizePriority=0, column size should be unmodified
|
||||||
// if SizePriority<>0 means variable size column, its size
|
// if SizePriority<>0 means variable size column whose width
|
||||||
// is the average avalilable size.
|
// is the average available size respecting each column
|
||||||
|
// MinSize and MaxSize constraints, such constraints
|
||||||
|
// are valid only if they are bigger than 0.
|
||||||
|
|
||||||
Count := 0;
|
widths := nil;
|
||||||
FixedSizeWidth := 0;
|
SetLength(widths, ColCount);
|
||||||
TotalWidth := 0;
|
|
||||||
for i:=0 to ColCount-1 do begin
|
availableSize := ClientWidth - GetBorderWidth;
|
||||||
|
for i:=0 to ColCount-1 do
|
||||||
|
with widths[i] do begin
|
||||||
|
aIndex := i;
|
||||||
GetAutoFillColumnInfo(i, aMin, aMax, aPriority);
|
GetAutoFillColumnInfo(i, aMin, aMax, aPriority);
|
||||||
AvailableSize := GetColWidths(i);
|
aWidth := GetColWidths(i);
|
||||||
if aPriority>0 then
|
if aPriority=0 then begin
|
||||||
Inc(Count)
|
Dec(availableSize, aWidth);
|
||||||
else
|
delete(widths, i, 1);
|
||||||
Inc(FixedSizeWidth, AvailableSize);
|
end
|
||||||
Inc(TotalWidth, AvailableSize);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if Count=0 then begin
|
if Length(widths)=0 then begin
|
||||||
//it's an autofillcolumns grid, so at least one
|
// it's an autofillcolumns grid either WITHOUT custom colums and
|
||||||
// of the columns must fill completely the grid's
|
// fixedCols=ColCount or WITH custom columns where all columns
|
||||||
// available width, let it be that column the last
|
// have PrioritySize=0, resize the last column (inherited behavior)
|
||||||
ForcedIndex := ColCount-1;
|
i := ColCount-1;
|
||||||
if ForcedIndex>=FixedCols then
|
if (i>=FixedCols) then // aMax of last column ...
|
||||||
Dec(FixedSizeWidth, GetColWidths(ForcedIndex));
|
SetColumnWidth(i, AvailableSize + GetColWidths(i));
|
||||||
Count := 1;
|
exit;
|
||||||
end else
|
end;
|
||||||
ForcedIndex := -1;
|
|
||||||
|
|
||||||
AvailableSize := ClientWidth - FixedSizeWidth - GetBorderWidth;
|
avgSize := availableSize div Length(widths);
|
||||||
if AvailableSize<0 then begin
|
|
||||||
// There is no space available to fill with
|
|
||||||
// Variable Size Columns, what to do?
|
|
||||||
|
|
||||||
// Simply set all Variable Size Columns
|
repeat
|
||||||
// to 0, decreasing the size beyond this
|
done := true;
|
||||||
// shouldn't be allowed.
|
for i:=Length(widths)-1 downto 0 do
|
||||||
for i:=0 to ColCount-1 do begin
|
with widths[i] do begin
|
||||||
GetAutoFillColumnInfo(i, aMin, aMax, aPriority);
|
isMax := ((aMax>0) and (avgSize>aMax));
|
||||||
if aPriority>0 then
|
isMin := ((aMin>0) and (avgSize<aMin));
|
||||||
SetColumnWidth(i, 0);
|
if isMax or isMin then begin
|
||||||
end;
|
if isMax then aWidth := aMax;
|
||||||
end else begin
|
if isMin then aWidth := aMin;
|
||||||
// Simpler case: There is actually available space to
|
SetColumnWidth(aIndex, aWidth);
|
||||||
// to be shared for variable size columns.
|
availableSize := Max(availableSize-aWidth, 0);
|
||||||
FixedSizeWidth := AvailableSize mod Count; // space left after filling columns
|
Delete(widths, i, 1);
|
||||||
AvailableSize := AvailableSize div Count;
|
if length(widths)>0 then
|
||||||
for i:=0 to ColCount-1 do begin
|
avgSize := availableSize div length(widths);
|
||||||
GetAutoFillColumnInfo(i, aMin, aMax, aPriority);
|
done := false;
|
||||||
if (APriority>0) or (i=ForcedIndex) then begin
|
break:
|
||||||
if i=ColCount-1 then
|
|
||||||
// the last column gets all space left
|
|
||||||
SetColumnWidth(i, AvailableSize + FixedSizeWidth)
|
|
||||||
else
|
|
||||||
SetColumnWidth(i, AvailableSize);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
until done;
|
||||||
|
|
||||||
|
if length(widths)>0 then begin
|
||||||
|
rest := availableSize mod length(widths);
|
||||||
|
for i:=0 to length(widths)-1 do
|
||||||
|
with widths[i] do begin
|
||||||
|
aWidth := Max(avgSize, 0);
|
||||||
|
if rest>0 then begin
|
||||||
|
inc(aWidth);
|
||||||
|
dec(rest);
|
||||||
end;
|
end;
|
||||||
|
SetColumnWidth(aIndex, aWidth);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
FUpdatingAutoFillCols:=False;
|
FUpdatingAutoFillCols:=False;
|
||||||
end;
|
end;
|
||||||
@ -8686,6 +8695,8 @@ procedure TCustomGrid.GetAutoFillColumnInfo(const Index: Integer; var aMin,aMax,
|
|||||||
var
|
var
|
||||||
C: TGridColumn;
|
C: TGridColumn;
|
||||||
begin
|
begin
|
||||||
|
aMin := DEFMINSIZE;
|
||||||
|
aMax := DEFMAXSIZE;
|
||||||
if Index<FixedCols then
|
if Index<FixedCols then
|
||||||
APriority := 0
|
APriority := 0
|
||||||
else if Columns.Enabled then begin
|
else if Columns.Enabled then begin
|
||||||
@ -9406,6 +9417,8 @@ begin
|
|||||||
cfg.setValue(cPath + '/index/value', c.Index);
|
cfg.setValue(cPath + '/index/value', c.Index);
|
||||||
if c.IsWidthStored then
|
if c.IsWidthStored then
|
||||||
cfg.setValue(cPath + '/width/value', c.Width);
|
cfg.setValue(cPath + '/width/value', c.Width);
|
||||||
|
if c.IsMinSizeStored then cfg.SetValue(cPath + '/minsize/value', c.MinSize);
|
||||||
|
if c.IsMaxSizeStored then cfg.SetValue(cPath + '/maxsize/value', c.MaxSize);
|
||||||
if c.IsAlignmentStored then
|
if c.IsAlignmentStored then
|
||||||
cfg.setValue(cPath + '/alignment/value', ord(c.Alignment));
|
cfg.setValue(cPath + '/alignment/value', ord(c.Alignment));
|
||||||
if c.IsLayoutStored then
|
if c.IsLayoutStored then
|
||||||
@ -9548,8 +9561,9 @@ begin
|
|||||||
cPath := Path + 'column' + IntToStr(i);
|
cPath := Path + 'column' + IntToStr(i);
|
||||||
c.index := cfg.getValue(cPath + '/index/value', i);
|
c.index := cfg.getValue(cPath + '/index/value', i);
|
||||||
s := cfg.GetValue(cPath + '/width/value', '');
|
s := cfg.GetValue(cPath + '/width/value', '');
|
||||||
if s<>'' then
|
if s<>'' then c.Width := StrToIntDef(s, DEFCOLWIDTH);
|
||||||
c.Width := StrToIntDef(s, 64);
|
c.MinSize := cfg.GetValue(cPath + '/minsize/value', DEFMINSIZE);
|
||||||
|
c.MaxSize := cfg.GetValue(cPath + '/maxsize/value', DEFMAXSIZE);
|
||||||
s := cfg.getValue(cPath + '/alignment/value', '');
|
s := cfg.getValue(cPath + '/alignment/value', '');
|
||||||
if s<>'' then
|
if s<>'' then
|
||||||
c.Alignment := TAlignment(StrToIntDef(s, 0));
|
c.Alignment := TAlignment(StrToIntDef(s, 0));
|
||||||
@ -12845,14 +12859,12 @@ end;
|
|||||||
|
|
||||||
function TGridColumn.GetDefaultMaxSize: Integer;
|
function TGridColumn.GetDefaultMaxSize: Integer;
|
||||||
begin
|
begin
|
||||||
// get a better default
|
Result := DEFMAXSIZE;
|
||||||
Result := 200;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGridColumn.GetDefaultMinSize: Integer;
|
function TGridColumn.GetDefaultMinSize: Integer;
|
||||||
begin
|
begin
|
||||||
// get a better default
|
result := DEFMINSIZE;
|
||||||
result := 10;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGridColumn.GetDefaultColor: TColor;
|
function TGridColumn.GetDefaultColor: TColor;
|
||||||
@ -12868,7 +12880,7 @@ end;
|
|||||||
|
|
||||||
function TGridColumn.GetDefaultSizePriority: Integer;
|
function TGridColumn.GetDefaultSizePriority: Integer;
|
||||||
begin
|
begin
|
||||||
Result := 1;
|
Result := DEFSIZEPRIORITY;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGridColumn.Assign(Source: TPersistent);
|
procedure TGridColumn.Assign(Source: TPersistent);
|
||||||
|
Loading…
Reference in New Issue
Block a user