1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| procedure TKGridColumn.Calc;
begin
DispatchRAZ(Self);
DispatchCalcRank(Self);
DispatchCalcTotal(Self);
end;
// RAZ
procedure TKGridColumn.DispatchRAZ(Contener: TWinControl);
var
Box: TKGridBox;
begin
Box := GetTopBoxOf(Contener); // retourner la 1ere boite (la plus haute)
while Box <> nil do
begin
Box.DispatchRank := 0; // Numéro de rangée
Box.DispatchTotal := 1; // Nombre de boites concernées (boite en cours incluse)
Box := GetNextBoxOf(Contener, Box); // retourner la boite suivante
end;
end;
// Définir la rangée de chaque boite :
// Mettre à gauche toutes celles qui le peuvent
// ensuite, augmenter le rank des autres
// etc...
procedure TKGridColumn.DispatchCalcRank(Contener: TWinControl);
var
Box, StartBox: TKGridBox;
Rank, vBottom: Integer;
CestFini: Boolean;
begin
Rank := 0;
repeat
Inc(Rank); // C'est la rangée d'affichage
// Touver la 1ere boite non traitée
StartBox := nil;
Box := GetTopBoxOf(Contener);
while Box <> nil do
begin
if Box.DispatchRank = 0 then
begin
StartBox := Box;
Break;
end;
Box := GetNextBoxOf(Contener, Box);
end;
Box := StartBox;
// J'ai une boite non traitée
if Box <> nil then
begin
Box.DispatchRank := Rank;
vBottom := Box.Area.Bottom;
// BOX SUIVANTES
Box := GetNextBoxOf(Contener, Box);
while Box <> nil do
begin
if (Box.DispatchRank = 0) and (Box.Area.Top > vBottom) then // On ne touche pas le boite précédente dans le Rank en cours
begin
Box.DispatchRank := Rank; // Affecter la rangée à cette boite
vBottom := Box.Area.Bottom;
end;
Box := GetNextBoxOf(Contener, Box);
end;
end;
// Vérifier s'il en reste à traiter
CestFini := True;
Box := GetTopBoxOf(Contener);
while Box <> nil do
begin
if Box.DispatchRank = 0 then
begin
CestFini := False;
Break;
end;
Box := GetNextBoxOf(Contener, Box);
end;
until CestFini;
end;
// Affecter a chaque boite le nombre de boites cotes a cotes
// pour en déduire la largeur lors de l'affichage
procedure TKGridColumn.DispatchCalcTotal(Contener: TWinControl);
var
i: Integer;
Box, BoxSide: TKGridBox;
RankList: TStringList;
function InRankList(Value: string): Boolean;
begin
Result := RankList.IndexOf(Value) > -1;
end;
begin
RankList := TStringList.Create; // Liste des ranks utilisés
try
Box := GetTopBoxOf(Contener); // 1ere boite en partant du haut
while Box <> nil do
begin
RankList.Clear;
RankList.AddObject(IntToStr(Box.DispatchRank), Box);
BoxSide := GetTopBoxOf(Contener);
while BoxSide <> nil do
begin
if BoxSide <> Box then
begin
if not InRankList(IntToStr(BoxSide.DispatchRank)) then
begin
// vérifier si 2 boites se chevauchent
if not ((Box.Area.Bottom < BoxSide.Area.Top) or (Box.Area.Top > BoxSide.Area.Bottom)) then
begin
RankList.AddObject(IntToStr(BoxSide.DispatchRank), BoxSide);
end;
end;
end;
BoxSide := GetNextBoxOf(Contener, BoxSide);
end;
for i := 0 to RankList.Count -1 do
begin
BoxSide := RankList.Objects[i] as TKGridBox;
BoxSide.DispatchTotal := RankList.Count;
end;
Box := GetNextBoxOf(Contener, Box);
end;
finally
RankList.Clear;
FreeAndNil(RankList);
end;
end; |
Partager