diff --git a/module-apps/DatabaseModel_old.hpp b/module-apps/DatabaseModel_old.hpp deleted file mode 100644 index 5b9f6525b..000000000 --- a/module-apps/DatabaseModel_old.hpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * @file DatabaseModel_old.hpp - * @author Robert Borzecki (robert.borzecki@mudita.com) - * @date 8 sie 2019 - * @brief - * @copyright Copyright (C) 2019 mudita.com - * @details This class is a template to create specialized instances of - * buffers that hold database records from given table. - */ -#ifndef MODULE_APPS_DATABASEMODEL_HPP_ -#define MODULE_APPS_DATABASEMODEL_HPP_ - -#include -#include -#include -#include - -#include "Application.hpp" - -namespace app -{ - - /* - * - */ - template class DatabaseModel_old - { - protected: - /** - * Number of elements requested from database in single message - */ - int pageSize = 1; - /** - * Pointer to application that owns the model - */ - Application *application; - /** - * Total number of records in database - */ - int recordsCount; - /** - * Index of first element in current page - */ - int firstIndex; - // vector that holds records received from database - first last records, than previous records and finally next - // records - std::vector> records; - - public: - virtual void requestRecordsCount() - {} - - virtual bool updateRecords(std::unique_ptr> records, - const uint32_t offset, - const uint32_t limit, - uint32_t count) - { - // calculate for which page is received data using offset value - - int page = getPage(offset); - int currentPage = firstIndex / pageSize; - - if ((page >= currentPage - 1) && (page <= currentPage + 1)) { - - // store new records - for (unsigned int i = 0; i < count; i++) { - auto ii = i + (pageSize * (page - currentPage) + pageSize) + offset % pageSize; - this->records[ii] = nullptr; - this->records[i + (pageSize * (page - currentPage) + pageSize) + offset % pageSize] = - std::make_shared(records.get()->operator[](i)); - // this->records[i+(pageSize*(page-currentPage) + pageSize)+offset% limit] = std::shared_ptr( new - // T(records.get()->operator [](i)) ); - } - - // return true (for refreshing window) only if current page was modified. - if (page == currentPage) - return true; - return false; - } - else { - // alarms are out of current scope - LOG_ERROR("Received records out of scope"); - return false; - } - return false; - } - - virtual void movePrevWindow() - { - - uint32_t currentPage = firstIndex / pageSize; - // check if it is possible to move to previous window - if (currentPage <= 0) - return; - - // erase records from next window - for (int i = 0; i < pageSize; i++) - if (records[i + 2 * pageSize]) { - records[i + 2 * pageSize] = nullptr; - } - - // moves current records to next records and prev records to current records - for (int i = 3 * pageSize - 1; i >= pageSize; --i) - records[i] = records[i - pageSize]; - - // clear first window to nullptr - for (int i = 0; i < pageSize; ++i) - records[i] = nullptr; - - // lock the application for keyboard input - application->blockEvents(true); - - // request records for next window - int prevPage = currentPage - 2; - if (prevPage >= 0) { - requestRecords(pageSize * prevPage, pageSize); - } - firstIndex -= pageSize; - if (firstIndex < 0) - firstIndex = 0; - } - - virtual void moveNextWindow() - { - - uint32_t currentPage = firstIndex / pageSize; - uint32_t pageCount = - (recordsCount % pageSize == 0) ? recordsCount / pageSize : (recordsCount / pageSize) + 1; - // check if it is possible to move to next window - if (currentPage >= pageCount) - return; - - // erase firswt window with indicies from 0 up to pageSize -1 - for (int i = 0; i < pageSize; i++) - if (records[i]) - records[i] = nullptr; - - // move current and next window so current window becomes prev window and next becomes current. - for (int i = 0; i < 2 * pageSize; ++i) - records[i] = records[i + pageSize]; - - // clear last window to nullptr - for (int i = 2 * pageSize; i < 3 * pageSize; ++i) - records[i] = nullptr; - - // lock the application for keyboard input - application->blockEvents(true); - - // request records for next window - uint32_t nextPage = currentPage + 2; - if (nextPage < pageCount) - requestRecords(pageSize * nextPage, pageSize); - firstIndex += pageSize; - if (firstIndex > recordsCount) - firstIndex = recordsCount / pageCount; - } - - virtual void requestRecords(const uint32_t offset, const uint32_t limit) = 0; - - bool setRecordsCount(int count) - { - - clear(); - recordsCount = count; - - // if there are any records request blocks of data from database using recordsLocalCount and requestSize. - if (recordsCount) { - - // TODO handle validation for firstIndex when number of records has decreased. - requestRecords(firstIndex, pageSize); - if (firstIndex + pageSize < recordsCount) - requestRecords(firstIndex + pageSize, pageSize); - return true; - } - return false; - } - - void setPageSize(int size) - { - clear(); - pageSize = size; - firstIndex = 0; - - records.resize(3 * pageSize); - std::fill(records.begin(), records.end(), nullptr); - } - - DatabaseModel_old(Application *app, int pageSize) - : pageSize{pageSize}, application{app}, recordsCount{-1}, firstIndex{0} - { - - records.resize(pageSize * 3); - std::fill(records.begin(), records.end(), nullptr); - } - - virtual ~DatabaseModel_old() - { - clear(); - } - - virtual void clear() - { - - for (int i = 0; i < pageSize * 3; i++) - records[i] = nullptr; - records.clear(); - firstIndex = 0; - recordsCount = -1; - } - - int getRecordsCount() - { - return recordsCount; - } - - int getPage(uint32_t index) - { - return (index % pageSize == 0) ? index / pageSize : (index / pageSize); - } - - /** - * @brief Returns database object under specified index. Performs forward and backward buffering. - * @index Index of the database element. Starts from 0 ( database objects have lowest ID equal to 1. ) - * @download Flag that controls whether model should download objects from database when requested object is - * outside visible window. - */ - std::shared_ptr getRecord(int index, bool download = true) - { - - // if index is greater than number of records or smaller than 0 - if ((index < 0) || (index > recordsCount - 1)) { - return nullptr; - } - // if index is in current window - if ((index >= firstIndex) && (index < firstIndex + pageSize)) { - return records[pageSize + index - firstIndex]; - } - // if download is false check if requested element is in any of the windows - if ((download == false) && (index >= firstIndex - pageSize) && (index < firstIndex + 2 * pageSize)) { - return records[pageSize + index - firstIndex]; - } - // if index is in next window - if (download && (index >= firstIndex + pageSize) && (index < firstIndex + 2 * pageSize)) { - std::shared_ptr record = records[pageSize + index - firstIndex]; - moveNextWindow(); - return record; - } - // if index is in previous window - if (download && (index >= firstIndex - pageSize) && (index < firstIndex)) { - std::shared_ptr record = records[index + pageSize - firstIndex]; - movePrevWindow(); - return record; - } - // if index is not in prev, current or next window - else if ((index < firstIndex - pageSize) || (index > firstIndex + 2 * pageSize)) { - int newCurrentPage = index / pageSize; - clear(); - firstIndex = pageSize * newCurrentPage; - // request current page - requestRecords(firstIndex, pageSize); - // if possible request previous page; - if (firstIndex - 1 > 0) - requestRecords(firstIndex - pageSize, pageSize); - // if possible request next window - if (firstIndex * (pageSize + 1) <= recordsCount - 1) - requestRecords(firstIndex + pageSize, pageSize); - - return nullptr; - } - return nullptr; - } - }; - -} /* namespace app */ - -#endif /* MODULE_APPS_DATABASEMODEL_HPP_ */ diff --git a/module-apps/application-calllog/CalllogModel.cpp b/module-apps/application-calllog/CalllogModel.cpp index 4182b2a9e..7abb856f1 100644 --- a/module-apps/application-calllog/CalllogModel.cpp +++ b/module-apps/application-calllog/CalllogModel.cpp @@ -12,6 +12,7 @@ #include "data/CallLogInternals.hpp" #include "CalllogModel.hpp" #include "UiCommonActions.hpp" +#include "ListView.hpp" using namespace calllog; @@ -55,27 +56,24 @@ bool CalllogModel::updateRecords(std::unique_ptr> rec #endif DatabaseModel::updateRecords(std::move(records), offset, limit, count); - - if (direction == style::listview::Direction::Top) - modelIndex = this->records.size() - 1; - else if (direction == style::listview::Direction::Bottom) - modelIndex = 0; - + modelIndex = 0; list->onProviderDataUpdate(); return true; } -gui::ListItem *CalllogModel::getItem(int index) +gui::ListItem *CalllogModel::getItem(gui::Order order) { - std::shared_ptr call = getRecord(modelIndex); + auto index = modelIndex; + if (order == gui::Order::Previous) { + index = records.size() - 1 - modelIndex; + } - if (direction == style::listview::Direction::Top) - modelIndex--; - else if (direction == style::listview::Direction::Bottom) - modelIndex++; + std::shared_ptr call = getRecord(index); - LOG_DEBUG("Model index: %d", modelIndex); + modelIndex++; + + LOG_DEBUG("Model index: %d", index); SettingsRecord &settings = application->getSettings(); if (call.get() == nullptr) { @@ -86,7 +84,7 @@ gui::ListItem *CalllogModel::getItem(int index) auto item = new gui::CalllogItem(this, !settings.timeFormat12); if (item != nullptr) { item->setCall(call); - item->setID(modelIndex); + item->setID(index); item->activatedCallback = [=](gui::Item &item) { LOG_INFO("activatedCallback"); std::unique_ptr data = std::make_unique(*call); diff --git a/module-apps/application-calllog/CalllogModel.hpp b/module-apps/application-calllog/CalllogModel.hpp index fbdcc5bc1..3259e5512 100644 --- a/module-apps/application-calllog/CalllogModel.hpp +++ b/module-apps/application-calllog/CalllogModel.hpp @@ -35,7 +35,7 @@ class CalllogModel : public app::DatabaseModel, public gui::ListI void requestRecords(const uint32_t offset, const uint32_t limit) override; // virtual methods for ListViewProvider - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; int getItemCount() const override { return recordsCount; diff --git a/module-apps/application-messages/models/BaseThreadRecordModel.cpp b/module-apps/application-messages/models/BaseThreadRecordModel.cpp index b7382f024..90bdfd28c 100644 --- a/module-apps/application-messages/models/BaseThreadRecordModel.cpp +++ b/module-apps/application-messages/models/BaseThreadRecordModel.cpp @@ -3,6 +3,7 @@ #include "application-messages/MessagesStyle.hpp" #include "service-db/api/DBServiceAPI.hpp" #include +#include "ListView.hpp" BaseThreadRecordModel::BaseThreadRecordModel(app::Application *app) : DatabaseModel(app) {} @@ -22,12 +23,7 @@ bool BaseThreadRecordModel::updateRecords(std::unique_ptrrecords.size() - 1; - else if (direction == style::listview::Direction::Bottom) - modelIndex = 0; - + modelIndex = 0; list->onProviderDataUpdate(); return true; } diff --git a/module-apps/application-messages/models/SearchResultsModel.cpp b/module-apps/application-messages/models/SearchResultsModel.cpp index a77a6098a..fc5e17389 100644 --- a/module-apps/application-messages/models/SearchResultsModel.cpp +++ b/module-apps/application-messages/models/SearchResultsModel.cpp @@ -11,9 +11,16 @@ namespace gui::model SearchResultsModel::SearchResultsModel(app::Application *app) : BaseThreadRecordModel(app) {} - gui::ListItem *SearchResultsModel::getItem(int index) + gui::ListItem *SearchResultsModel::getItem(gui::Order order) { + auto index = modelIndex; + if (order == gui::Order::Previous) { + index = records.size() - 1 - modelIndex; + } + std::shared_ptr thread = getRecord(index); + modelIndex++; + if (thread.get() == nullptr) { return nullptr; } @@ -29,7 +36,7 @@ namespace gui::model // The only thing that differs with ThreadModel actually - here show what was found ret->setPreview(thread->snippet); } - ret->setID(index); + ret->setID(modelIndex); return ret; } diff --git a/module-apps/application-messages/models/ThreadModel.cpp b/module-apps/application-messages/models/ThreadModel.cpp index 427f2ecd5..229317567 100644 --- a/module-apps/application-messages/models/ThreadModel.cpp +++ b/module-apps/application-messages/models/ThreadModel.cpp @@ -7,14 +7,16 @@ ThreadModel::ThreadModel(app::Application *app) : BaseThreadRecordModel(app) {} -gui::ListItem *ThreadModel::getItem(int index) +gui::ListItem *ThreadModel::getItem(gui::Order order) { - std::shared_ptr thread = getRecord(modelIndex); + auto index = modelIndex; + if (order == gui::Order::Previous) { + modelIndex = records.size() - 1 - modelIndex; + } - if (direction == style::listview::Direction::Top) - modelIndex--; - else if (direction == style::listview::Direction::Bottom) - modelIndex++; + std::shared_ptr thread = getRecord(index); + + modelIndex++; if (thread.get() == nullptr) { return nullptr; @@ -23,7 +25,7 @@ gui::ListItem *ThreadModel::getItem(int index) auto item = new gui::ThreadItem(this); if (item != nullptr) { item->setThreadItem(thread); - item->setID(modelIndex); + item->setID(index); item->activatedCallback = [=](gui::Item &item) { LOG_INFO("ThreadItem ActivatedCallback"); if (application) { diff --git a/module-apps/application-messages/models/ThreadModel.hpp b/module-apps/application-messages/models/ThreadModel.hpp index 23fad365b..7a2723900 100644 --- a/module-apps/application-messages/models/ThreadModel.hpp +++ b/module-apps/application-messages/models/ThreadModel.hpp @@ -6,5 +6,5 @@ class ThreadModel : public BaseThreadRecordModel { public: ThreadModel(app::Application *app); - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; }; diff --git a/module-apps/application-messages/widgets/SMSTemplateModel.cpp b/module-apps/application-messages/widgets/SMSTemplateModel.cpp index 840c6ff9b..0b045c08f 100644 --- a/module-apps/application-messages/widgets/SMSTemplateModel.cpp +++ b/module-apps/application-messages/widgets/SMSTemplateModel.cpp @@ -5,6 +5,7 @@ #include "application-messages/MessagesStyle.hpp" #include "application-messages/ApplicationMessages.hpp" #include +#include "ListView.hpp" SMSTemplateModel::SMSTemplateModel(app::Application *app) : DatabaseModel(app) {} @@ -36,14 +37,23 @@ bool SMSTemplateModel::updateRecords(std::unique_ptronProviderDataUpdate(); + modelIndex = 0; return true; } return false; } -gui::ListItem *SMSTemplateModel::getItem(int index) +gui::ListItem *SMSTemplateModel::getItem(gui::Order order) { + auto index = modelIndex; + if (order == gui::Order::Previous) { + index = records.size() - 1 - modelIndex; + } + auto templ = getRecord(index); + + modelIndex++; + if (!templ) { return nullptr; } diff --git a/module-apps/application-messages/widgets/SMSTemplateModel.hpp b/module-apps/application-messages/widgets/SMSTemplateModel.hpp index 23dc65b19..83ab60adf 100644 --- a/module-apps/application-messages/widgets/SMSTemplateModel.hpp +++ b/module-apps/application-messages/widgets/SMSTemplateModel.hpp @@ -20,7 +20,7 @@ class SMSTemplateModel : public app::DatabaseModel, public gu uint32_t count) override; void requestRecords(const uint32_t offset, const uint32_t limit) override; - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; int getItemCount() const override { diff --git a/module-apps/application-notes/NotesModel.cpp b/module-apps/application-notes/NotesModel.cpp index 0fd206f83..174520fa3 100644 --- a/module-apps/application-notes/NotesModel.cpp +++ b/module-apps/application-notes/NotesModel.cpp @@ -10,6 +10,7 @@ #include "widgets/NotesItem.hpp" #include "NotesModel.hpp" +#include "ListView.hpp" NotesModel::NotesModel(app::Application *app) : DatabaseModel(app) {} @@ -19,7 +20,7 @@ NotesModel::~NotesModel() void NotesModel::requestRecordsCount() { - recordsCount = DBServiceAPI::NotesGetCount(application); + recordsCount = DBServiceAPI::NotesGetCount(application); // request first and second page if possible if (recordsCount > 0) { @@ -45,16 +46,23 @@ bool NotesModel::updateRecords(std::unique_ptr> records #endif DatabaseModel::updateRecords(std::move(records), offset, limit, count); + modelIndex = 0; list->onProviderDataUpdate(); return true; } -gui::ListItem *NotesModel::getItem(int index) +gui::ListItem *NotesModel::getItem(gui::Order order) { + auto index = modelIndex; + if (order == gui::Order::Previous) { + index = records.size() - 1 - modelIndex; + } std::shared_ptr note = getRecord(index); + modelIndex++; + SettingsRecord &settings = application->getSettings(); if (note == nullptr) diff --git a/module-apps/application-notes/NotesModel.hpp b/module-apps/application-notes/NotesModel.hpp index 85ec37c5b..d8a5d8a71 100644 --- a/module-apps/application-notes/NotesModel.hpp +++ b/module-apps/application-notes/NotesModel.hpp @@ -35,7 +35,7 @@ class NotesModel : public app::DatabaseModel, public gui::ListItemP void requestRecords(const uint32_t offset, const uint32_t limit) override; // virtual methods for ListViewProvider - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; int getItemCount() const override { return recordsCount; diff --git a/module-apps/application-phonebook/models/PhonebookModel.cpp b/module-apps/application-phonebook/models/PhonebookModel.cpp index 88d1c0294..d72263e75 100644 --- a/module-apps/application-phonebook/models/PhonebookModel.cpp +++ b/module-apps/application-phonebook/models/PhonebookModel.cpp @@ -5,6 +5,7 @@ #include "../widgets/PhonebookItem.hpp" #include "service-db/api/DBServiceAPI.hpp" #include "UiCommonActions.hpp" +#include "ListView.hpp" PhonebookModel::PhonebookModel(app::Application *app) : DatabaseModel(app) {} @@ -24,7 +25,7 @@ void PhonebookModel::requestRecordsCount() void PhonebookModel::requestRecords(const uint32_t offset, const uint32_t limit) { - LOG_DEBUG("Req off: %u, limit: %u", offset, limit); + // LOG_DEBUG("REQUESTED!!!!!!!!!!!!! eq off: %u, limit: %u", offset, limit); DBServiceAPI::ContactGetLimitOffset(application, offset, limit); } @@ -47,15 +48,23 @@ bool PhonebookModel::updateRecords(std::unique_ptr> r #endif DatabaseModel::updateRecords(std::move(records), offset, limit, count); + modelIndex = 0; list->onProviderDataUpdate(); return true; } -gui::ListItem *PhonebookModel::getItem(int index) +gui::ListItem *PhonebookModel::getItem(gui::Order order) { + auto index = modelIndex; + if (order == gui::Order::Previous) { + index = records.size() - 1 - modelIndex; + } + std::shared_ptr contact = getRecord(index); + modelIndex++; + if (contact == nullptr) { return nullptr; } diff --git a/module-apps/application-phonebook/models/PhonebookModel.hpp b/module-apps/application-phonebook/models/PhonebookModel.hpp index 375052482..f26c742e4 100644 --- a/module-apps/application-phonebook/models/PhonebookModel.hpp +++ b/module-apps/application-phonebook/models/PhonebookModel.hpp @@ -17,7 +17,7 @@ class PhonebookModel : public app::DatabaseModel, public gui::Lis /** * Number of favourite records in the database. */ - uint32_t favouriteCount = 0; + uint32_t favouriteCount = 0; public: PhonebookModel(app::Application *app); @@ -32,7 +32,7 @@ class PhonebookModel : public app::DatabaseModel, public gui::Lis void requestRecords(const uint32_t offset, const uint32_t limit) override; // virtual methods for ListViewProvider - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; int getItemCount() const override { diff --git a/module-apps/application-phonebook/models/SearchResultsModel.cpp b/module-apps/application-phonebook/models/SearchResultsModel.cpp index 16d77abbf..cb053bd0c 100644 --- a/module-apps/application-phonebook/models/SearchResultsModel.cpp +++ b/module-apps/application-phonebook/models/SearchResultsModel.cpp @@ -5,8 +5,9 @@ #include "../widgets/PhonebookItem.hpp" #include "service-db/api/DBServiceAPI.hpp" #include "UiCommonActions.hpp" +#include "ListView.hpp" -SearchResultsModel::SearchResultsModel(app::Application *app) : DatabaseModel(app) +SearchResultsModel::SearchResultsModel(app::Application *app) : application{app} {} SearchResultsModel::~SearchResultsModel() @@ -14,34 +15,49 @@ SearchResultsModel::~SearchResultsModel() results = nullptr; } -void SearchResultsModel::requestFavouritesCount() -{ - favouriteCount = DBServiceAPI::ContactGetCount(application, true); -} - -void SearchResultsModel::requestRecordsCount() -{} void SearchResultsModel::requestRecords(const uint32_t offset, const uint32_t limit) { internalOffset = offset; + internalLimit = limit; list->onProviderDataUpdate(); } -gui::ListItem *SearchResultsModel::getItem(int index) +gui::ListItem *SearchResultsModel::getItem(gui::Order order) { - if (results != nullptr && internalOffset + index < results->size()) { - auto contact = std::make_shared(results->at(internalOffset + index)); + auto index = 0; + if (order == gui::Order::Previous) { + index = internalOffset + internalLimit; + } + if (order == gui::Order::Next) { + index = internalOffset; + } + + if (results != nullptr && index < static_cast(results->size()) && index >= 0) { + auto contact = std::make_shared(results->at(index)); // std::shared_ptr contact = getRecord(index); + if (order == gui::Order::Previous) { + internalOffset--; + } + if (order == gui::Order::Next) { + internalOffset++; + } + if (contact == nullptr) { return nullptr; } + LOG_DEBUG("index: %d, id: %d, name: %s %s, fav: %d", + index, + internalOffset, + contact->primaryName.c_str(), + contact->alternativeName.c_str(), + contact->isOnFavourites); gui::PhonebookItem *item = new gui::PhonebookItem(); if (item != nullptr) { item->setContact(contact); - item->setID(index); + item->setID(internalOffset); item->activatedCallback = [=](gui::Item &item) { LOG_INFO("activatedCallback"); std::unique_ptr data = std::make_unique(contact); diff --git a/module-apps/application-phonebook/models/SearchResultsModel.hpp b/module-apps/application-phonebook/models/SearchResultsModel.hpp index 25e09b1cc..f7a373870 100644 --- a/module-apps/application-phonebook/models/SearchResultsModel.hpp +++ b/module-apps/application-phonebook/models/SearchResultsModel.hpp @@ -3,30 +3,26 @@ #include #include "Application.hpp" -#include "DatabaseModel.hpp" #include "Interface/ContactRecord.hpp" #include "ListItemProvider.hpp" #include "NotesRecord.hpp" -class SearchResultsModel : public gui::ListItemProvider, public app::DatabaseModel +class SearchResultsModel : public gui::ListItemProvider { - uint32_t internalOffset = 0; + int internalOffset = 0; + int internalLimit = 0; + app::Application *application = nullptr; + std::shared_ptr> results; public: SearchResultsModel(app::Application *app); virtual ~SearchResultsModel(); // virtual methods for ListViewProvider - gui::ListItem *getItem(int index) override; + gui::ListItem *getItem(gui::Order order) override; int getItemCount() const override; void setResults(std::shared_ptr> _results); - void requestFavouritesCount(); - void requestRecordsCount() override; void requestRecords(const uint32_t offset, const uint32_t limit) override; - - private: - std::shared_ptr> results; - uint32_t favouriteCount = 0; }; diff --git a/module-apps/application-phonebook/widgets/PhonebookListView.cpp b/module-apps/application-phonebook/widgets/PhonebookListView.cpp index 918a59364..7eb45d05c 100644 --- a/module-apps/application-phonebook/widgets/PhonebookListView.cpp +++ b/module-apps/application-phonebook/widgets/PhonebookListView.cpp @@ -9,43 +9,89 @@ namespace gui void PhonebookListView::addLabelMarker(gui::PhonebookItem *item) { - if (!(labelMark == (item)->getLabelMarker())) { + if (direction == style::listview::Direction::Bottom) { + if (!(labelMark == (item)->getLabelMarker())) { - labelMark = (item)->getLabelMarker(); + labelMark = (item)->getLabelMarker(); - gui::PhonebookItem *phonebookLabel = new gui::PhonebookItem(); - phonebookLabel->setMarkerItem(labelMark); + gui::PhonebookItem *phonebookLabel = new gui::PhonebookItem(); + phonebookLabel->setMarkerItem(labelMark); - body->addWidget(phonebookLabel); + body->addWidget(phonebookLabel); + } + } + if (direction == style::listview::Direction::Top) { + + if (currentPageSize == 0) { + labelMark = (item)->getLabelMarker(); + return; + } + else if (!(labelMark == (item)->getLabelMarker())) { + + previousLabelMark = labelMark; + labelMark = (item)->getLabelMarker(); + + gui::PhonebookItem *phonebookLabel = new gui::PhonebookItem(); + phonebookLabel->setMarkerItem(previousLabelMark); + body->removeWidget(item); + body->addWidget(phonebookLabel); + body->addWidget(item); + } } } void PhonebookListView::addItemsOnPage() { - auto itemsOnPage = 0; + currentPageSize = 0; + // auto itemsOnPage = 0; + ListItem *item = nullptr; + ListItem *previousListItem = nullptr; + labelMark = ""; + previousLabelMark = ""; - ListItem *item = nullptr; - labelMark = ""; + while ((item = provider->getItem(getOrderFromDirection())) != nullptr) { - while ((item = provider->getItem(itemsOnPage)) != nullptr) { - - addLabelMarker(reinterpret_cast(item)); + if (direction == style::listview::Direction::Bottom) { + addLabelMarker(reinterpret_cast(item)); + } body->addWidget(item); if (item->visible != true) { - currentPageSize = itemsOnPage; + + if (direction == style::listview::Direction::Top) { + body->removeWidget(item); + body->removeWidget(previousListItem); + gui::PhonebookItem *phonebookLabel = new gui::PhonebookItem(); + + if (!(previousLabelMark == labelMark)) { + phonebookLabel->setMarkerItem(labelMark); + } + + body->addWidget(phonebookLabel); + + currentPageSize--; + } + // currentPageSize = itemsOnPage; break; } - itemsOnPage++; + // itemsOnPage++; + + if (direction == style::listview::Direction::Top) { + addLabelMarker(reinterpret_cast(item)); + } + + previousListItem = item; + // previousLabelMark = reinterpret_cast(item)->getLabelMarker(); + currentPageSize++; + + LOG_DEBUG("Page id %d, Label Mark %s", currentPageSize, labelMark.c_str()); + LOG_DEBUG("Page id %d, Prev Mark %s", currentPageSize, previousLabelMark.c_str()); listSpanItem = new Span(Axis::Y, itemSpanSize); body->addWidget(listSpanItem); } - - if (currentPageSize == 0) - currentPageSize = itemsOnPage; } } /* namespace gui */ diff --git a/module-apps/application-phonebook/widgets/PhonebookListView.hpp b/module-apps/application-phonebook/widgets/PhonebookListView.hpp index abeb6a36e..2c4e73cd2 100644 --- a/module-apps/application-phonebook/widgets/PhonebookListView.hpp +++ b/module-apps/application-phonebook/widgets/PhonebookListView.hpp @@ -12,7 +12,8 @@ namespace gui class PhonebookListView : public ListView { - UTF8 labelMark = ""; + UTF8 labelMark = ""; + UTF8 previousLabelMark = ""; void addItemsOnPage() override; void addLabelMarker(PhonebookItem *item); diff --git a/module-apps/application-phonebook/windows/PhonebookSearchResults.cpp b/module-apps/application-phonebook/windows/PhonebookSearchResults.cpp index 997dc0a2d..2b6b2db05 100644 --- a/module-apps/application-phonebook/windows/PhonebookSearchResults.cpp +++ b/module-apps/application-phonebook/windows/PhonebookSearchResults.cpp @@ -59,7 +59,6 @@ namespace gui void PhonebookSearchResults::onBeforeShow(ShowMode mode, SwitchData *data) { setFocusItem(searchResultList); - searchResultsModel->requestFavouritesCount(); } bool PhonebookSearchResults::onInput(const InputEvent &inputEvent) diff --git a/module-gui/gui/widgets/CMakeLists.txt b/module-gui/gui/widgets/CMakeLists.txt index d3afc37f2..f8bfc985d 100644 --- a/module-gui/gui/widgets/CMakeLists.txt +++ b/module-gui/gui/widgets/CMakeLists.txt @@ -22,8 +22,6 @@ target_sources( ${PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/Style.cpp" "${CMAKE_CURRENT_LIST_DIR}/InputMode.cpp" "${CMAKE_CURRENT_LIST_DIR}/GridLayout.cpp" - "${CMAKE_CURRENT_LIST_DIR}/ListView_old.cpp" - "${CMAKE_CURRENT_LIST_DIR}/ListItemProvider_old.cpp" PUBLIC "${CMAKE_CURRENT_LIST_DIR}/Alignment.hpp" "${CMAKE_CURRENT_LIST_DIR}/BottomBar.hpp" @@ -43,7 +41,5 @@ target_sources( ${PROJECT_NAME} "${CMAKE_CURRENT_LIST_DIR}/Layout.hpp" "${CMAKE_CURRENT_LIST_DIR}/TopBar.hpp" "${CMAKE_CURRENT_LIST_DIR}/Text.hpp" - "${CMAKE_CURRENT_LIST_DIR}/ListView_old.hpp" - "${CMAKE_CURRENT_LIST_DIR}/ListItemProvider_old.hpp" ) diff --git a/module-gui/gui/widgets/ListItemProvider.hpp b/module-gui/gui/widgets/ListItemProvider.hpp index 40ef33e55..7ceb94798 100644 --- a/module-gui/gui/widgets/ListItemProvider.hpp +++ b/module-gui/gui/widgets/ListItemProvider.hpp @@ -1,23 +1,27 @@ #pragma once #include "ListItem.hpp" -#include "ListView.hpp" namespace gui { class ListView; + enum class Order + { + Next, + Previous + }; + class ListItemProvider { public: - ListView *list = nullptr; - style::listview::Direction direction = style::listview::Direction::Bottom; + ListView *list = nullptr; virtual int getItemCount() const = 0; - virtual ListItem *getItem(int index) = 0; + virtual ListItem *getItem(Order order) = 0; virtual void requestRecords(const uint32_t offset, const uint32_t limit) = 0; }; diff --git a/module-gui/gui/widgets/ListItemProvider_old.cpp b/module-gui/gui/widgets/ListItemProvider_old.cpp deleted file mode 100644 index e47380b9f..000000000 --- a/module-gui/gui/widgets/ListItemProvider_old.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ListItemProvider.cpp - * - * Created on: 11 mar 2019 - * Author: robert - */ - -#include "ListItemProvider_old.hpp" - -namespace gui -{ - - ListItemProvider_old::ListItemProvider_old() - {} - - ListItemProvider_old::~ListItemProvider_old() - {} - - ListItem *ListItemProvider_old::getItem( - int index, int firstElement, int prevElement, uint32_t count, int remaining, bool topDown) - { - return nullptr; - } - -} /* namespace gui */ diff --git a/module-gui/gui/widgets/ListItemProvider_old.hpp b/module-gui/gui/widgets/ListItemProvider_old.hpp deleted file mode 100644 index e57f82582..000000000 --- a/module-gui/gui/widgets/ListItemProvider_old.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ListItemProvider_old.hpp - * - * Created on: 11 mar 2019 - * Author: robert - */ - -#ifndef MIDDLEWARES_GUI_WIDGETS_LISTITEMPROVIDER_HPP_ -#define MIDDLEWARES_GUI_WIDGETS_LISTITEMPROVIDER_HPP_ - -#include "ListItem.hpp" -#include "ListView_old.hpp" - -namespace gui -{ - - class ListView_old; - - /// something between cache and factory for list view - it provides next elements requested by ListView_old - /// it can only be used in combination with DatabaseModel which uses asynchronous request via application - /// and caches elements requested from database - class ListItemProvider_old - { - protected: - ListView_old *list = nullptr; - - public: - ListItemProvider_old(); - virtual ~ListItemProvider_old(); - - virtual int getItemCount() const = 0; - /** - * @brief Requests from Provider element that is no index position out of givent count of visible elements - * @param index Index of the visible element. - * @param firstElement Index of the first element on the displayed list. - * @param prevElement Index of the previous element. - * @param count Number of the elements visible in the list view widget. - * @param topDown defines if elements are to be filled starting from the top of list - */ - virtual ListItem *getItem( - int index, int firstElement, int prevElement, uint32_t count, int remaining = 0, bool topDown = true); - }; - -} /* namespace gui */ - -#endif /* MIDDLEWARES_GUI_WIDGETS_LISTITEMPROVIDER_HPP_ */ diff --git a/module-gui/gui/widgets/ListView.cpp b/module-gui/gui/widgets/ListView.cpp index 13a4c5521..e674320a1 100644 --- a/module-gui/gui/widgets/ListView.cpp +++ b/module-gui/gui/widgets/ListView.cpp @@ -158,6 +158,14 @@ namespace gui refresh(); } + Order ListView::getOrderFromDirection() + { + if (direction == style::listview::Direction::Bottom) + return Order::Next; + + return Order::Previous; + } + void ListView::resizeWithScroll() { if (scroll->shouldShowScroll(currentPageSize, elementsCount)) { @@ -174,7 +182,7 @@ namespace gui ListItem *item = nullptr; - while ((item = provider->getItem(itemsOnPage)) != nullptr) { + while ((item = provider->getItem(getOrderFromDirection())) != nullptr) { body->addWidget(item); @@ -234,8 +242,6 @@ namespace gui return (startIndex - (minLimit - currentPageSize) >= 0 ? minLimit : currentPageSize); }; - provider->direction = direction; - if (direction == style::listview::Direction::Bottom) { body->setReverseOrder(false); @@ -274,11 +280,15 @@ namespace gui startIndex = startIndex - currentPageSize >= 0 ? startIndex - currentPageSize : 0; } - LOG_DEBUG("Start off: %u, limit: %u, page: %u", startIndex, calculateLimit(), currentPageSize); + auto temp = startIndex - (minLimit - currentPageSize) >= 0 ? startIndex - (minLimit - currentPageSize) : 0; - provider->requestRecords( - startIndex - (minLimit - currentPageSize) >= 0 ? startIndex - (minLimit - currentPageSize) : 0, - calculateLimit()); + LOG_DEBUG("Start off: %u, offset send: %u, limit: %u, page: %u", + startIndex, + temp, + calculateLimit(), + currentPageSize); + + provider->requestRecords(temp, calculateLimit()); } return true; diff --git a/module-gui/gui/widgets/ListView.hpp b/module-gui/gui/widgets/ListView.hpp index 755d6ace3..ade32df2a 100644 --- a/module-gui/gui/widgets/ListView.hpp +++ b/module-gui/gui/widgets/ListView.hpp @@ -41,6 +41,7 @@ namespace gui void setFocus(); void refresh(); void resizeWithScroll(); + Order getOrderFromDirection(); bool listPageEndReached(); public: diff --git a/module-gui/gui/widgets/ListView_old.cpp b/module-gui/gui/widgets/ListView_old.cpp deleted file mode 100644 index ec65d2a5a..000000000 --- a/module-gui/gui/widgets/ListView_old.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* - * ListView_old.cpp - * - * Created on: 11 mar 2019 - * Author: robert - */ -#include - -#include "ListView_old.hpp" -#include - -namespace gui -{ - - ListView_old::ListView_old() - : firstIndex{0}, lastIndex{0}, elementsCount{4}, drawSeparators{true}, drawVerticalScroll{true}, - orientation{ListView_old::ORIENTATION_TOP_DOWN}, maxElements{4}, - selectedIndex{0}, listMode{ListView_old::MODE_PAGE}, pageSize{4} - { - - setPenFocusWidth(0); - setPenWidth(0); - - scroll = new Rect(this, 0, 0, 0, 0); - scroll->setRadius(3); - scroll->setFilled(true); - scroll->setFillColor(Color{0, 0}); - } - - ListView_old::ListView_old(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h) - : Rect{parent, x, y, w, h}, firstIndex{0}, lastIndex{0}, elementsCount{4}, drawSeparators{true}, - drawVerticalScroll{true}, orientation{ListView_old::ORIENTATION_TOP_DOWN}, maxElements{4}, - selectedIndex{0}, listMode{ListView_old::MODE_PAGE}, pageSize{4} - { - - setPenFocusWidth(0); - setPenWidth(0); - - scroll = new Rect(this, 0, 0, 0, 0); - scroll->setRadius(3); - scroll->setFilled(true); - scroll->setFillColor(Color{0, 0}); - } - - ListView_old::~ListView_old() - { - - clearItems(); - } - - /** - * For MODE_PAGE: - * When new number of elements is provided list checks if currently visible items are still valid. - * If value of the first index is invalid then new value is calculated using number of all elements - * and defined size of page(number of visible elements). - * Last index is calculated using value of first index and page size. If value is too big it is reduced - * to index of the last element. - * if index of selected element is invalid after change new value is set to the index of the last element - * in the list. - */ - void ListView_old::setElementsCount(int count) - { - elementsCount = count; - if (listMode == ListView_old::MODE_PAGE) { - if (firstIndex > elementsCount) - firstIndex = (elementsCount / pageSize) * pageSize; - lastIndex = firstIndex + pageSize - 1; - if (lastIndex > elementsCount - 1) - lastIndex = elementsCount - 1; - if (selectedIndex > lastIndex) - selectedIndex = lastIndex; - } - updateScrollDimenstions(); - } - - void ListView_old::setDrawSeparators(bool value) - { - drawSeparators = value; - } - - void ListView_old::setOrientation(int orientation) - { - if (orientation == ListView_old::ORIENTATION_BOTTOM_UP) - this->orientation = ListView_old::ORIENTATION_BOTTOM_UP; - else if (orientation == ListView_old::ORIENTATION_TOP_DOWN) - this->orientation = ListView_old::ORIENTATION_TOP_DOWN; - } - - void ListView_old::drawScroll(bool value) - { - drawVerticalScroll = value; - scroll->visible = value; - } - - void ListView_old::setMaxElements(int value) - { - maxElements = value; - } - - void ListView_old::setProvider(ListItemProvider_old *provider) - { - this->provider = provider; - } - - void ListView_old::clearItems() - { - - for (auto item : items) { - removeWidget(item); - delete (item); - } - - items.clear(); - } - - void ListView_old::clear() - { - clearItems(); - - firstIndex = 0; - lastIndex = 0; - selectedIndex = 0; - - updateScrollDimenstions(); - } - - void ListView_old::updatePageItems() - { - - int prevIndex = firstIndex - 1; - for (int i = 0; i < pageSize; i++) { - - ListItem *item = provider->getItem(firstIndex + i, firstIndex, prevIndex, pageSize); - if (item != nullptr) { - addWidget(item); - items.push_back(item); - prevIndex++; - } - } - - // calculate height of the item using list's height and pageSize - uint32_t itemWidth = widgetArea.w; - if (drawVerticalScroll) - itemWidth -= 10; - - int availableHeight = widgetArea.h - pageSize; - if (availableHeight < 0) - availableHeight = 0; - int itemHeight = availableHeight / pageSize; - - int verticalPosition; - if (orientation == ORIENTATION_TOP_DOWN) - verticalPosition = 0; - else - verticalPosition = widgetArea.h; - - auto it = items.begin(); - for (unsigned int i = 0; i < items.size(); i++) { - if (availableHeight > 0) { - - itemHeight = (*it)->area(Area::Min).h; - gui::BoundingBox bbox = (*it)->widgetArea; - bbox.h = itemHeight; - bbox.w = itemWidth; - - if (orientation == ORIENTATION_TOP_DOWN) { - bbox.y = verticalPosition; - verticalPosition += itemHeight + 1; // 1 for separator - } - else { - verticalPosition -= itemHeight - 1; // 1 for separator - bbox.y = verticalPosition; - } - - (*it)->setBoundingBox(bbox); - - // if list has focus and it is visible mark selected element - if (visible) { - if ((int)(i + firstIndex) == selectedIndex) - (*it)->setFocus(true); - } - - availableHeight -= itemHeight; - } - std::advance(it, 1); - } - } - - bool ListView_old::onInput(const InputEvent &inputEvent) - { - - if ((inputEvent.state == InputEvent::State::keyReleasedShort) && (inputEvent.keyCode == KeyCode::KEY_ENTER)) { - return onActivated(nullptr); - } - - if ((inputEvent.state == InputEvent::State::keyReleasedShort) && (inputEvent.keyCode == KeyCode::KEY_UP)) { - if (orientation == ORIENTATION_TOP_DOWN) { - if (listMode == MODE_PAGE) { - if (selectedIndex > firstIndex) { - selectedIndex--; - return true; - } - if (selectedIndex == firstIndex) { - if (firstIndex > 0) { - firstIndex -= pageSize; - if (firstIndex < 0) - firstIndex = 0; - lastIndex = firstIndex + pageSize - 1; - if (lastIndex > elementsCount - 1) - lastIndex = elementsCount - 1; - selectedIndex = lastIndex; - updateScrollDimenstions(); - return true; - } - } - } - else { - // TODO implement continuous mode - } - } - else if (orientation == ORIENTATION_BOTTOM_UP) { - // TODO implement BOTTOM_UP orientation - } - } - else if ((inputEvent.state == InputEvent::State::keyReleasedShort) && - (inputEvent.keyCode == KeyCode::KEY_DOWN)) { - if (orientation == ORIENTATION_TOP_DOWN) { - if (listMode == MODE_PAGE) { - if (selectedIndex < lastIndex) { - selectedIndex++; - return true; - } - if (selectedIndex == lastIndex) { - if (lastIndex < elementsCount - 1) { - firstIndex += pageSize; - if (firstIndex > elementsCount - 1) - firstIndex = elementsCount - 1; - lastIndex = firstIndex + pageSize - 1; - if (lastIndex > elementsCount - 1) - lastIndex = elementsCount - 1; - selectedIndex = firstIndex; - updateScrollDimenstions(); - return true; - } - } - } - else { // continuous mode - } - } - else { // BOTTOM_UP - } - } - return false; - } - - void ListView_old::updateContinousItems() - {} - - // TODO reuse items if possible - void ListView_old::updateItems() - { - - // remove old items - clearItems(); - - if (provider == nullptr) - return; - - elementsCount = provider->getItemCount(); - - if (listMode == ListView_old::MODE_PAGE) { - updatePageItems(); - } - else if (listMode == ListView_old::MODE_CONTINUOUS) { - updateContinousItems(); - } - } - - ListItem *ListView_old::getSelectedItem() - { - // return object only if there are any items in the list - if (elementsCount) { - auto it = items.begin(); - std::advance(it, selectedIndex - firstIndex); - return *it; - } - return nullptr; - } - - std::list ListView_old::buildDrawList() - { - - // check if widget is visible - if (visible == false) { - return std::list(); - } - - updateItems(); - - // uint8_t* bBuf = gui::Rect::buildDrawList(bSize, bCount); - return gui::Rect::buildDrawList(); - } - - void ListView_old::setMode(int mode) - { - if ((mode == ListView_old::MODE_PAGE) || (mode == ListView_old::MODE_CONTINUOUS)) - listMode = mode; - } - - void ListView_old::setPageSize(int size) - { - pageSize = size; - } - - bool ListView_old::onActivated(void *data) - { - - // return if list doesn't have focus - if (focus == false) - return false; - - // if there are any elements in the list - if (elementsCount > 0) { - // select item that has focus - auto it = items.begin(); - std::advance(it, selectedIndex - firstIndex); - return (*it)->onActivated(data); - } - - return false; - } - - bool ListView_old::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) - { - Rect::onDimensionChanged(oldDim, newDim); - updateScrollDimenstions(); - return true; - } - - void ListView_old::updateScrollDimenstions() - { - if ((widgetArea.w > 10) && (widgetArea.h > 10)) { - if (drawVerticalScroll) - scroll->visible = true; - - uint32_t pagesCount = 1; - if (pageSize) { - pagesCount = (elementsCount % pageSize == 0) ? elementsCount / pageSize : elementsCount / pageSize + 1; - if (pagesCount == 0) { - disableScroll(); - return; - } - } - - uint32_t currentPage = selectedIndex / pageSize; - uint32_t pageHeight = widgetArea.h / pagesCount; - - scroll->setPosition(widgetArea.w - 7, pageHeight * currentPage); - scroll->setSize(7, pageHeight); - } - // not enough space - disable scroll - else { - disableScroll(); - } - } - - void ListView_old::disableScroll() - { - scroll->setSize(0, 0); - scroll->visible = false; - } - -} /* namespace gui */ diff --git a/module-gui/gui/widgets/ListView_old.hpp b/module-gui/gui/widgets/ListView_old.hpp deleted file mode 100644 index 4b517a4b7..000000000 --- a/module-gui/gui/widgets/ListView_old.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * ListView_old.h - * - * Created on: 11 mar 2019 - * Author: robert - */ - -#ifndef MIDDLEWARES_GUI_WIDGETS_LISTVIEW_HPP_ -#define MIDDLEWARES_GUI_WIDGETS_LISTVIEW_HPP_ - -#include -#include "Rect.hpp" -#include "ListItemProvider_old.hpp" - -namespace gui -{ - - class ListItemProvider_old; - - /// fixed size and application Vertical ListView_old to be used with ListItemProvider_old and DatabaseModel only. - /// For simple vertical list with no external model use VBox - class ListView_old : public Rect - { - protected: - // id of the first element visible on the list (location depends on orientation) - int firstIndex; - // index of last visible item - int lastIndex; - // defines total number of elements in the list - int elementsCount; - // defines whether separator should be placed between elements - bool drawSeparators; - // defines whether scroll bar should be drawn on the right side of list widget - bool drawVerticalScroll; - // defines whether first element is on bottom of widget ( BOTTOM_UP ) or on top of widget ( TOP_BOTTOM ) - int orientation; - // maximum number of elements that can be displayed on the screen - int maxElements; - // index of the currently selected element - int selectedIndex; - // vector that holds currently visible list of items - std::list items; - // pointer to the item provider object - ListItemProvider_old *provider = nullptr; - // rounded rectangle used to draw scroll bar - Rect *scroll; - // space available for new items - this will change after any new item retrieved from provider - int listMode; - int pageSize; - - virtual void updatePageItems(); - void updateContinousItems(); - void clearItems(); - void updateScrollDimenstions(); - void disableScroll(); - - public: - static const int ORIENTATION_TOP_DOWN = 0x01; - static const int ORIENTATION_BOTTOM_UP = 0x02; - // list items has same height, incrementing beyond last or first item will cause all items to be changed - static const int MODE_PAGE = 0x04; - // following item will be displayed as long there is available space. Height of the items must be provided by - // the items. - static const int MODE_CONTINUOUS = 0x08; - - ListView_old(); - ListView_old(Item *parent, uint32_t x, uint32_t y, uint32_t w, uint32_t h); - virtual ~ListView_old(); - - // virtual methods for list view - virtual void setElementsCount(int count); - virtual void setDrawSeparators(bool value); - virtual void setOrientation(int orientation); - virtual void drawScroll(bool value); - virtual void setMaxElements(int value); - virtual void setProvider(ListItemProvider_old *provider); - virtual void setMode(int mode); - virtual void setPageSize(int size); - virtual ListItem *getSelectedItem(); - /* - * Acquire and/or update items using item provider - */ - virtual void updateItems(); - /** - * removes all data stored in the list and resets size and position to 0 - */ - virtual void clear(); - - // virtual methods from Item - std::list buildDrawList() override; - bool onInput(const InputEvent &inputEvent) override; - bool onActivated(void *data) override; - bool onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim) override; - }; - -} /* namespace gui */ - -#endif /* MIDDLEWARES_GUI_WIDGETS_LISTVIEW_HPP_ */