Fixed SUPER old bug in ListWindow and ScrollAdapter where an adapter

refresh may scroll the view to a weird location. Also cleaned up
ScrollPosition handling.
This commit is contained in:
casey langen 2017-03-21 22:39:27 -07:00
parent 5cc5727fdd
commit 4f346aea5a
5 changed files with 26 additions and 34 deletions

View File

@ -73,7 +73,7 @@ namespace cursespp {
virtual void SetDisplaySize(size_t width, size_t height) = 0;
virtual size_t GetEntryCount() = 0;
virtual EntryPtr GetEntry(ScrollableWindow* window, size_t index) = 0;
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition *result = NULL) = 0;
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition& result) = 0;
};
typedef std::shared_ptr<IScrollAdapter> IScrollAdapterPtr;

View File

@ -191,7 +191,7 @@ void ListWindow::PageDown() {
void ListWindow::ScrollTo(size_t index) {
this->GetScrollAdapter().DrawPage(
this, index, &this->GetMutableScrollPosition());
this, index, this->GetMutableScrollPosition());
this->Invalidate();
}
@ -215,7 +215,7 @@ void ListWindow::SetSelectedIndex(size_t index) {
this->GetScrollAdapter().DrawPage(
this,
this->scrollPosition.firstVisibleEntryIndex,
&this->GetMutableScrollPosition());
this->GetMutableScrollPosition());
this->Invalidate();
@ -257,7 +257,7 @@ void ListWindow::OnAdapterChanged() {
void ListWindow::OnDimensionsChanged() {
ScrollableWindow::OnDimensionsChanged();
this->ScrollTo(this->selectedIndex);
this->ScrollTo(this->GetScrollPosition().firstVisibleEntryIndex);
}
IScrollAdapter::ScrollPosition& ListWindow::GetMutableScrollPosition() {

View File

@ -72,20 +72,22 @@ void ScrollAdapterBase::GetVisibleItems(
to the end. if we don't try to back up a bit until we can fill
the buffer */
int totalHeight = (int) this->height;
int entryCount = (int) this->GetEntryCount();
/* forward search first... */
int end = (int) GetEntryCount();
for (int i = (int) desired; i < end && totalHeight > 0; i++) {
/* we assume the general case -- we're some where in the middle of the
list. we'll start from the specified first item and work our way down */
for (int i = (int) desired; i < entryCount && totalHeight > 0; i++) {
EntryPtr entry = this->GetEntry(window, i);
entry->SetWidth(this->width);
totalHeight -= entry->GetLineCount();
target.push_back(entry);
}
/* however, if the list is short, we can actually draw more items above
the specified one. let's work our way backwards! */
if (totalHeight > 0) {
target.clear();
/* oops, let's move backwards from the end */
totalHeight = this->height;
int i = GetEntryCount() - 1;
while (i >= 0 && totalHeight >= 0) {
@ -108,15 +110,7 @@ void ScrollAdapterBase::GetVisibleItems(
start = actual;
}
void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, ScrollPosition *result) {
if (result != NULL) {
result->visibleEntryCount = 0;
result->firstVisibleEntryIndex = 0;
result->lineCount = 0;
result->totalEntries = 0;
result->logicalIndex = 0;
}
void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, ScrollPosition& result) {
WINDOW* window = scrollable->GetContent();
werase(window);
@ -131,7 +125,7 @@ void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, Scr
/* unfortunately this needs to go here so the GetEntry() method knows
what the the implied focus is */
result->logicalIndex = index;
//result.logicalIndex = index;
std::deque<EntryPtr> visible;
size_t topIndex; /* calculated by GetVisibleItems */
@ -181,11 +175,9 @@ void ScrollAdapterBase::DrawPage(ScrollableWindow* scrollable, size_t index, Scr
}
}
if (result != NULL) {
result->visibleEntryCount = visible.size();
result->firstVisibleEntryIndex = topIndex;
result->lineCount = drawnLines;
result->totalEntries = GetEntryCount();
result->logicalIndex = index;
}
result.visibleEntryCount = visible.size();
result.firstVisibleEntryIndex = topIndex;
result.lineCount = drawnLines;
result.totalEntries = GetEntryCount();
//result.logicalIndex = index;
}

View File

@ -56,7 +56,7 @@ namespace cursespp {
virtual void DrawPage(
ScrollableWindow* window,
size_t index,
ScrollPosition *result = nullptr);
ScrollPosition& result);
virtual size_t GetEntryCount() = 0;
virtual EntryPtr GetEntry(cursespp::ScrollableWindow* window, size_t index) = 0;

View File

@ -52,7 +52,7 @@ public:
virtual void SetDisplaySize(size_t width, size_t height) { }
virtual size_t GetEntryCount() { return 0; }
virtual EntryPtr GetEntry(cursespp::ScrollableWindow* window, size_t index) { return IScrollAdapter::EntryPtr(); }
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition *result = NULL) { }
virtual void DrawPage(ScrollableWindow* window, size_t index, ScrollPosition& result) { }
};
static EmptyAdapter emptyAdapter;
@ -63,7 +63,7 @@ static EmptyAdapter emptyAdapter;
GetScrollAdapter().DrawPage( \
this, \
pos.firstVisibleEntryIndex, \
&pos); \
pos); \
} \
ScrollableWindow::ScrollableWindow(std::shared_ptr<IScrollAdapter> adapter, IWindow *parent)
@ -144,7 +144,7 @@ bool ScrollableWindow::KeyPress(const std::string& key) {
void ScrollableWindow::Redraw() {
IScrollAdapter *adapter = &GetScrollAdapter();
ScrollPos &pos = this->GetMutableScrollPosition();
adapter->DrawPage(this, pos.firstVisibleEntryIndex, &pos);
adapter->DrawPage(this, pos.firstVisibleEntryIndex, pos);
this->Invalidate();
}
@ -158,7 +158,7 @@ void ScrollableWindow::OnAdapterChanged() {
}
else {
ScrollPos &pos = this->GetMutableScrollPosition();
adapter->DrawPage(this, pos.firstVisibleEntryIndex, &pos);
adapter->DrawPage(this, pos.firstVisibleEntryIndex, pos);
this->Invalidate();
}
}
@ -169,7 +169,7 @@ void ScrollableWindow::Show() {
}
void ScrollableWindow::ScrollToTop() {
GetScrollAdapter().DrawPage(this, 0, &this->GetMutableScrollPosition());
GetScrollAdapter().DrawPage(this, 0, this->GetMutableScrollPosition());
this->Invalidate();
}
@ -177,7 +177,7 @@ void ScrollableWindow::ScrollToBottom() {
GetScrollAdapter().DrawPage(
this,
GetScrollAdapter().GetEntryCount(),
&this->GetMutableScrollPosition());
this->GetMutableScrollPosition());
this->Invalidate();
}
@ -187,7 +187,7 @@ void ScrollableWindow::ScrollUp(int delta) {
if (pos.firstVisibleEntryIndex > 0) {
GetScrollAdapter().DrawPage(
this, pos.firstVisibleEntryIndex - delta, &pos);
this, pos.firstVisibleEntryIndex - delta, pos);
this->Invalidate();
}
@ -197,7 +197,7 @@ void ScrollableWindow::ScrollDown(int delta) {
ScrollPos &pos = this->GetMutableScrollPosition();
GetScrollAdapter().DrawPage(
this, pos.firstVisibleEntryIndex + delta, &pos);
this, pos.firstVisibleEntryIndex + delta, pos);
this->Invalidate();
}