void ListView::Expand(unsigned index, bool enable, bool recursive) { if (!hierarchyMode_) return; unsigned numItems = GetNumItems(); if (index >= numItems) return; UIElement* item = GetItem(index++); SetItemExpanded(item, enable); int baseIndent = item->GetIndent(); PODVector<bool> expanded((unsigned)(baseIndent + 1)); expanded[baseIndent] = enable; contentElement_->DisableLayoutUpdate(); while (index < numItems) { item = GetItem(index++); int indent = item->GetIndent(); if (indent <= baseIndent) break; // Propagate the state to children when it is recursive if (recursive) SetItemExpanded(item, enable); // Use the parent expanded flag to influence the visibility of its children bool visible = enable && expanded[indent - 1]; item->SetVisible(visible); if (indent >= (int)expanded.Size()) expanded.Resize((unsigned)(indent + 1)); expanded[indent] = visible && GetItemExpanded(item); } contentElement_->EnableLayoutUpdate(); contentElement_->UpdateLayout(); }
void ListView::RemoveItem(UIElement* item, unsigned index) { if (!item) return; unsigned numItems = GetNumItems(); for (unsigned i = index; i < numItems; ++i) { if (GetItem(i) == item) { item->SetSelected(false); selections_.Remove(i); unsigned removed = 1; if (hierarchyMode_) { // Remove any child items in hierarchy mode if (GetItemHierarchyParent(item)) { int baseIndent = item->GetIndent(); for (unsigned j = i + 1; ; ++j) { UIElement* childItem = GetItem(i + 1); if (!childItem) break; if (childItem->GetIndent() > baseIndent) { childItem->SetSelected(false); selections_.Erase(j); contentElement_->RemoveChildAtIndex(i + 1); overlayContainer_->RemoveChildAtIndex(i + 1); ++removed; } else break; } } // Check if the parent of removed item still has other children if (i > 0) { int baseIndent = item->GetIndent(); UIElement* prevKin = GetItem(i - 1); // Could be parent or sibling if (prevKin->GetIndent() < baseIndent) { UIElement* nextKin = GetItem(i + 1); // Could be sibling or parent-sibling or 0 if index out of bound if (!nextKin || nextKin->GetIndent() < baseIndent) { // If we reach here then the parent has no other children SetItemHierarchyParent(prevKin, false); } } } // Remove the overlay at the same index overlayContainer_->RemoveChildAtIndex(i); } // If necessary, shift the following selections if (!selections_.Empty()) { for (unsigned j = 0; j < selections_.Size(); ++j) { if (selections_[j] > i) selections_[j] -= removed; } UpdateSelectionEffect(); } contentElement_->RemoveChildAtIndex(i); break; } } }