oldIndexToNewIndex method

_ReindexResult oldIndexToNewIndex(
  1. int? index,
  2. _PopUpList? popUpList
)

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);
}