Fixed a really old bug in ListWindow where you could scroll past the last

item if items in the viewport were of heterogenous size.
This commit is contained in:
casey langen 2016-12-08 20:25:17 -08:00
parent b3b423f931
commit be9284e4ef
2 changed files with 44 additions and 0 deletions

View File

@ -118,6 +118,39 @@ void ListWindow::OnInvalidated() {
this->Invalidated(this, this->GetSelectedIndex());
}
bool ListWindow::IsSelectedItemCompletelyVisible() {
IScrollAdapter& adapter = this->GetScrollAdapter();
ScrollPos spos = this->GetScrollPosition();
size_t first = spos.firstVisibleEntryIndex;
size_t last = first + spos.visibleEntryCount - 1;
if (last <= spos.logicalIndex) {
/* get the height of all the visible items combined. */
int sum = 0;
for (size_t i = first; i <= spos.logicalIndex; i++) {
sum += adapter.GetEntry(this, i)->GetLineCount();
}
int delta = this->GetContentHeight() - sum;
/* special case -- the last item in the adapter is selected
and the heights match exactly -- we're at the end! */
if (delta == 0 && last == adapter.GetEntryCount() - 1) {
return true;
}
/* compare the visible height to the actual content
height. if the visible items are taller, and th selected
item is the last one, it means it's partially obscured. */
if (delta <= 0) {
return false;
}
}
return true;
}
void ListWindow::ScrollDown(int delta) {
IScrollAdapter& adapter = this->GetScrollAdapter();
@ -137,7 +170,16 @@ void ListWindow::ScrollDown(int delta) {
}
this->SetSelectedIndex(newIndex);
this->ScrollTo(drawIndex);
/* when scrolling down it's possible for the last item to be
the selection, and partially obscured. if we hit this case, we
just continue scrolling until the selected item is completely
visible to the user. */
while (!IsSelectedItemCompletelyVisible()) {
this->ScrollTo(++drawIndex);
}
}
}

View File

@ -81,6 +81,8 @@ namespace cursespp {
virtual IScrollAdapter::ScrollPosition& GetMutableScrollPosition();
private:
virtual bool IsSelectedItemCompletelyVisible();
IScrollAdapter* adapter;
IScrollAdapter::ScrollPosition scrollPosition;
size_t selectedIndex;