Skip to content

Commit

Permalink
Dynamically load/unload list items while scrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
robsdedude committed Mar 17, 2020
1 parent f84f682 commit 3bf2ed2
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 10 deletions.
113 changes: 108 additions & 5 deletions src/Views/ListView/listView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,107 @@ ListView::ListView(std::vector<Homebrew> homebrews)
{
log_printf(DBG_DEBUG, "posY: %d", posY);
log_printf(DBG_DEBUG, "homebrews size: %d", homebrews.size());
for (Homebrew hb : homebrews)
this->homebrews = homebrews;
listItems = std::vector<ListItem*>(homebrews.size(), nullptr);
LoadListItems();
}

long ListView::_LoadPreviousListItems(long firstDisplayed, long firstToLoad, long maxLoad)
{
long loaded = 0;
for (long i = firstDisplayed; i >= firstToLoad; i--)
{
if (!listItems[i])
{
listItems[i] = new ListItem(homebrews[i]);
if (++loaded > maxLoad)
{
break;
}
}
}
return loaded;
}

long ListView::_LoadShownListItems(long firstDisplayed, long lastDisplayed, long maxLoad)
{
long loaded = 0;
for (long i = firstDisplayed; i <= lastDisplayed; i++)
{
listItems.emplace_back(hb);
if (!listItems[i])
{
listItems[i] = new ListItem(homebrews[i]);
if (++loaded > maxLoad)
{
break;
}
}
}
return loaded;
}

long ListView::_LoadNextListItems(long lastDisplayed, long lastToLoad, long maxLoad)
{
long loaded = 0;
for (long i = lastDisplayed; i <= lastToLoad; i++)
{
if (!listItems[i])
{
listItems[i] = new ListItem(homebrews[i]);
if (++loaded > maxLoad)
{
break;
}
}
}
return loaded;
}

void ListView::LoadListItems()
{
auto first = (long)firstDisplayedItem();
auto last = (long)lastDisplayedItem();
long firstToLoad = std::max<long>(first - PRE_RENDER_EXTRA_LIST_ITEM, 0);
long lastToLoad = std::min<long>(last + PRE_RENDER_EXTRA_LIST_ITEM, listItems.size());
long loaded = 0;
for (long i = 0; i < firstToLoad; i++)
{
if (listItems[i])
{
delete listItems[i];
listItems[i] = nullptr;
}
}
for (long i = lastToLoad; i < (long)listItems.size(); i++)
{
if (listItems[i])
{
delete listItems[i];
listItems[i] = nullptr;
}
}

loaded += _LoadShownListItems(first, last, MAX_LOAD_LIST_ITEMS_PER_CYCLE);
if (loaded >= MAX_LOAD_LIST_ITEMS_PER_CYCLE)
return;

if (scrollSpeed >= 0)
{
// preferably pre-load further down the list
loaded += _LoadNextListItems(first, last, MAX_LOAD_LIST_ITEMS_PER_CYCLE);
if (loaded >= MAX_LOAD_LIST_ITEMS_PER_CYCLE)
return;
loaded += _LoadPreviousListItems(first, last, MAX_LOAD_LIST_ITEMS_PER_CYCLE);
if (loaded >= MAX_LOAD_LIST_ITEMS_PER_CYCLE)
return;
} else {
// preferably pre-load further up the list
loaded += _LoadPreviousListItems(first, last, MAX_LOAD_LIST_ITEMS_PER_CYCLE);
if (loaded >= MAX_LOAD_LIST_ITEMS_PER_CYCLE)
return;
loaded += _LoadNextListItems(first, last, MAX_LOAD_LIST_ITEMS_PER_CYCLE);
if (loaded >= MAX_LOAD_LIST_ITEMS_PER_CYCLE)
return;
}
}

Expand Down Expand Up @@ -127,7 +225,7 @@ int ListView::HandleInput(int focus, const Input& input)
log_printf(DBG_DEBUG, "Clicked, adding view...");
try
{
Activity::get_instance()->AddView(std::make_shared<HomebrewView>(listItems.at(selectedItem).homebrew));
Activity::get_instance()->AddView(std::make_shared<HomebrewView>(homebrews.at(selectedItem)));
}
catch (const std::exception& ex)
{
Expand Down Expand Up @@ -205,7 +303,7 @@ int ListView::HandleInput(int focus, const Input& input)
log_printf(DBG_DEBUG, "Pressed, adding view...");
try
{
Activity::get_instance()->AddView(std::make_shared<HomebrewView>(listItems.at(selectedItem).homebrew));
Activity::get_instance()->AddView(std::make_shared<HomebrewView>(homebrews.at(selectedItem)));
}
catch (const std::exception& ex)
{
Expand All @@ -227,6 +325,8 @@ int ListView::HandleInput(int focus, const Input& input)
}
}

LoadListItems();

return 0;
}

Expand All @@ -246,7 +346,10 @@ int ListView::Display()
}
for (int i = firstDisplayedItem(); i <= lastDisplayedItem(); i++)
{
listItems[i].Display(itemPosY(i), i == selectedItem, itemHighlightAlpha);
if(listItems[i])
{
listItems[i]->Display(itemPosY(i), i == selectedItem, itemHighlightAlpha);
}
}
if (itemHighlightDirection)
{
Expand Down
9 changes: 8 additions & 1 deletion src/Views/ListView/listView.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define LIST_MAX_Y 543 // This ordinate is included too
#define LIST_RANGE_Y (LIST_MAX_Y - LIST_MIN_Y)
#define LIST_HEIGHT (LIST_RANGE_Y + 1)
#define PRE_RENDER_EXTRA_LIST_ITEM 30
#define MAX_LOAD_LIST_ITEMS_PER_CYCLE 1

// Max speed px/ms above which selected item is no more selected
#define LIST_SELECTION_MAX_SPEED 0.000070
Expand All @@ -27,7 +29,9 @@ class ListView: public View {
virtual bool IsReadyToShow() { return true; };

protected:
std::vector<ListItem> listItems;
std::vector<Homebrew> homebrews;
std::vector<ListItem*> listItems;
void LoadListItems();

private:
Font font_43;
Expand All @@ -49,4 +53,7 @@ class ListView: public View {
unsigned int lastFullyDisplayedItem();
int coordinateToItem(double coordY);
int updateScrollSpeed(double &scrollSpeed, unsigned long timeDif);
long _LoadPreviousListItems(long firstDisplayed, long firstToLoad, long maxLoad);
long _LoadShownListItems(long firstDisplayed, long lastDisplayed, long maxLoad);
long _LoadNextListItems(long lastDisplayed, long lastToLoad, long loadMax);
};
10 changes: 6 additions & 4 deletions src/Views/ListView/searchView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ int SearchView::Display()
auto db = Database::get_instance();
std::vector<Homebrew> hbs;
hbs = db->Search(SearchQuery(_ime_search_view_result->userText));
listItems.clear();
for (Homebrew hb : hbs)
{
listItems.emplace_back(hb);
homebrews = hbs;
for (ListItem* item: listItems) {
delete item;
}
listItems.clear();
listItems = std::vector<ListItem*>(homebrews.size(), nullptr);
LoadListItems();
lastQuery = _ime_search_view_result->userText;
}
else
Expand Down

0 comments on commit 3bf2ed2

Please sign in to comment.