oldIndexToNewIndex method
This function takes the old index
of a child and calculates the new one by considering
all the pending updates
.
This method can return null
if the child no longer exists (for example,
all elements of a remove interval disappear when it becomes a resizing interval).
Implementation
_ReindexResult oldIndexToNewIndex(int? index, _PopUpList? popUpList) {
var needsRebuild = false;
var clearLayoutOffset = false;
var discardElement = false;
for (final upd in _intervalListManager.updates) {
if (upd.popUpList == popUpList) {
// stessa popup, ci interessa
} else if (upd.flags.hasPopupDrop && popUpList == upd.toPopUpList) {
// l'elemento sta per posarsi nella nostra popup, ci interessa
} else {
// siamo in un'altra popup, questo update non ci interessa
continue;
}
if (upd.flags.hasPopupDrop && upd.popUpList == popUpList) {
// l'elemento sta per uscire dalla nostra popup per posarsi in un'altra
// index è la posizione dell'elemento relativa alla popup, dobbiamo sommare upd.index ch'è la posizione
// della vecchia popup in cui si inserirà il primo elemento dell'intervallo
index = index! + upd.index;
popUpList = upd.toPopUpList; // cambio popup!
needsRebuild = true;
clearLayoutOffset = true;
continue;
}
if (index! >= upd.index && index < upd.index + upd.oldBuildCount) {
// l'indice ricade nell'intervallo di update (il vecchio)
if (upd.flags.hasPopupDrop) {
// l'indice ricade in un vecchio intervallo che sta per essere completamente sovrascritto dagli elementi
// che prevongono da un'altra popup, pertanto l'elemento non esiste più
index = null;
// clearLayoutOffset = true;
break;
} else if (upd.flags.hasPopupPick) {
// l'elemento si sta per spostare in un'altra popup
// index va reso relativo alla nuova popup, pertanto va sotratto la posizione in cui si trovava nella
// vecchia popup
index -= upd.index;
popUpList = upd.toPopUpList; // cambio popup!
needsRebuild = true;
clearLayoutOffset = true;
continue;
}
if (index >= upd.index + upd.newBuildCount) {
// l'elemento non esiste più, ricadeva nella parte finale del vecchio intervallo che era più grande
// di quello nuovo
index = null;
break;
}
if (upd.flags.hasClearLayoutOffset) {
// se c'è il flag CLEAR_LAYOUT_OFFSET....
if (index != upd.index || !upd.flags.hasKeepFirstLayoutOffset) {
// azzera l'offset se non è il primo elemento dell'update, oppure se è il primo elemento
// quest'ultimo non ha il flag kEEP_FIRST_LAYOUT_OFFSET
clearLayoutOffset = true;
}
}
// l'indice ricade nell'update, pertanto necessita di un rebuild
needsRebuild = true;
if (upd.flags.hasDiscardElement) {
discardElement = true;
}
}
if (index >= upd.index + upd.oldBuildCount) {
// se l'indice ricade dopo quest'update, l'indice va riadattato di un delta dato dalla lunghezza
// del nuovo intervallo meno quella del vecchio intervallo (per esempio, se l'update agisce su 4 elementi
// che vengono convertiti in soli 3 nuovi elementi, il delta da sommare all'indice è -1)
index += upd.skipCount;
}
}
return _ReindexResult(
index, needsRebuild, discardElement, clearLayoutOffset, popUpList);
}