mirror of
https://github.com/clangen/musikcube.git
synced 2024-10-02 13:02:35 +00:00
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:
parent
b3b423f931
commit
be9284e4ef
@ -118,6 +118,39 @@ void ListWindow::OnInvalidated() {
|
|||||||
this->Invalidated(this, this->GetSelectedIndex());
|
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) {
|
void ListWindow::ScrollDown(int delta) {
|
||||||
IScrollAdapter& adapter = this->GetScrollAdapter();
|
IScrollAdapter& adapter = this->GetScrollAdapter();
|
||||||
|
|
||||||
@ -137,7 +170,16 @@ void ListWindow::ScrollDown(int delta) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->SetSelectedIndex(newIndex);
|
this->SetSelectedIndex(newIndex);
|
||||||
|
|
||||||
this->ScrollTo(drawIndex);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +81,8 @@ namespace cursespp {
|
|||||||
virtual IScrollAdapter::ScrollPosition& GetMutableScrollPosition();
|
virtual IScrollAdapter::ScrollPosition& GetMutableScrollPosition();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual bool IsSelectedItemCompletelyVisible();
|
||||||
|
|
||||||
IScrollAdapter* adapter;
|
IScrollAdapter* adapter;
|
||||||
IScrollAdapter::ScrollPosition scrollPosition;
|
IScrollAdapter::ScrollPosition scrollPosition;
|
||||||
size_t selectedIndex;
|
size_t selectedIndex;
|
||||||
|
Loading…
Reference in New Issue
Block a user