NS_IMETHODIMP nsListBoxBodyFrame::ScrollToIndex(PRInt32 aRowIndex) { if (( aRowIndex < 0 ) || (mRowHeight == 0)) return NS_OK; PRInt32 newIndex = aRowIndex; PRInt32 delta = mCurrentIndex > newIndex ? mCurrentIndex - newIndex : newIndex - mCurrentIndex; PRBool up = newIndex < mCurrentIndex; // Check to be sure we're not scrolling off the bottom of the tree PRInt32 lastPageTopRow = GetRowCount() - (GetAvailableHeight() / mRowHeight); if (lastPageTopRow < 0) lastPageTopRow = 0; if (aRowIndex > lastPageTopRow) return NS_OK; mCurrentIndex = newIndex; // Since we're going to flush anyway, we need to not do this off an event DoInternalPositionChangedSync(up, delta); // This change has to happen immediately. // Flush any pending reflow commands. // XXXbz why, exactly? mContent->GetDocument()->FlushPendingNotifications(Flush_Layout); return NS_OK; }
nsresult nsListBoxBodyFrame::InternalPositionChangedCallback() { nsListScrollSmoother* smoother = GetSmoother(); if (smoother->mDelta == 0) return NS_OK; mCurrentIndex += smoother->mDelta; if (mCurrentIndex < 0) mCurrentIndex = 0; return DoInternalPositionChangedSync(smoother->mDelta < 0, smoother->mDelta < 0 ? -smoother->mDelta : smoother->mDelta); }
nsresult nsListBoxBodyFrame::EnsureIndexIsVisible(PRInt32 aRowIndex) { if (aRowIndex < 0) return NS_ERROR_ILLEGAL_VALUE; PRInt32 rows = 0; if (mRowHeight) rows = GetAvailableHeight()/mRowHeight; if (rows <= 0) rows = 1; PRInt32 bottomIndex = mCurrentIndex + rows; // if row is visible, ignore if (mCurrentIndex <= aRowIndex && aRowIndex < bottomIndex) return NS_OK; PRInt32 delta; bool up = aRowIndex < mCurrentIndex; if (up) { delta = mCurrentIndex - aRowIndex; mCurrentIndex = aRowIndex; } else { // Check to be sure we're not scrolling off the bottom of the tree if (aRowIndex >= GetRowCount()) return NS_ERROR_ILLEGAL_VALUE; // Bring it just into view. delta = 1 + (aRowIndex-bottomIndex); mCurrentIndex += delta; } // Safe to not go off an event here, since this is coming from the // box object. DoInternalPositionChangedSync(up, delta); return NS_OK; }