From 70830e0b746a42a5093b5ab75c9e52b277cb5911 Mon Sep 17 00:00:00 2001 From: Hugo Saint-Vignes Date: Wed, 10 Jun 2020 11:31:10 +0200 Subject: [PATCH] [escher] Scroll speed increase for long repetition in selectable table Change-Id: Idfc3edcedff5a933b6f2168b475e22ea56ea0ab0 --- apps/home/controller.cpp | 20 +++++++------- apps/shared/store_selectable_table_view.cpp | 27 ++++++++++--------- apps/shared/store_selectable_table_view.h | 2 +- escher/include/escher/selectable_table_view.h | 1 + escher/src/selectable_table_view.cpp | 27 ++++++++++++++++--- 5 files changed, 49 insertions(+), 28 deletions(-) diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 50af28bfb..754a367dd 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -60,7 +60,7 @@ Controller::Controller(Responder * parentResponder, SelectableTableViewDataSourc bool Controller::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { AppsContainer * container = AppsContainer::sharedAppsContainer(); - ::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(selectionDataSource()->selectedRow()*k_numberOfColumns+selectionDataSource()->selectedColumn()+1); + ::App::Snapshot * selectedSnapshot = container->appSnapshotAtIndex(selectionDataSource()->selectedRow() * k_numberOfColumns + selectionDataSource()->selectedColumn() + 1); if (ExamModeConfiguration::appIsForbiddenInExamMode(selectedSnapshot->descriptor()->name(), GlobalPreferences::sharedGlobalPreferences()->examMode())) { App::app()->displayWarning(I18n::Message::ForbidenAppInExamMode1, I18n::Message::ForbidenAppInExamMode2); } else { @@ -72,14 +72,14 @@ bool Controller::handleEvent(Ion::Events::Event event) { } if (event == Ion::Events::Home || event == Ion::Events::Back) { - return m_view.selectableTableView()->selectCellAtLocation(0,0); + return m_view.selectableTableView()->selectCellAtLocation(0, 0); } - if (event == Ion::Events::Right && selectionDataSource()->selectedRow() < numberOfRows()) { - return m_view.selectableTableView()->selectCellAtLocation(0, selectionDataSource()->selectedRow()+1); + if (event == Ion::Events::Right && selectionDataSource()->selectedRow() < numberOfRows() - 1) { + return m_view.selectableTableView()->selectCellAtLocation(0, selectionDataSource()->selectedRow() + 1); } if (event == Ion::Events::Left && selectionDataSource()->selectedRow() > 0) { - return m_view.selectableTableView()->selectCellAtLocation(numberOfColumns()-1, selectionDataSource()->selectedRow()-1); + return m_view.selectableTableView()->selectCellAtLocation(numberOfColumns() - 1, selectionDataSource()->selectedRow() - 1); } return false; @@ -97,7 +97,7 @@ View * Controller::view() { } int Controller::numberOfRows() const { - return ((numberOfIcons()-1)/k_numberOfColumns)+1; + return ((numberOfIcons() - 1) / k_numberOfColumns) + 1; } int Controller::numberOfColumns() const { @@ -123,7 +123,7 @@ int Controller::reusableCellCount() const { void Controller::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { AppCell * appCell = (AppCell *)cell; AppsContainer * container = AppsContainer::sharedAppsContainer(); - int appIndex = (j*k_numberOfColumns+i)+1; + int appIndex = (j * k_numberOfColumns + i) + 1; if (appIndex >= container->numberOfApps()) { appCell->setVisible(false); } else { @@ -148,7 +148,7 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo * unvisible. This trick does not create an endless loop as we ensure not to * stay on a unvisible cell and to initialize the first cell on a visible one * (so the previous one is always visible). */ - int appIndex = (t->selectedColumn()+t->selectedRow()*k_numberOfColumns)+1; + int appIndex = (t->selectedColumn() + t->selectedRow() * k_numberOfColumns) + 1; if (appIndex >= AppsContainer::sharedAppsContainer()->numberOfApps()) { t->selectCellAtLocation(previousSelectedCellX, previousSelectedCellY); } @@ -166,8 +166,8 @@ void Controller::tableViewDidChangeSelectionAndDidScroll(SelectableTableView * t * redrawing takes time and is visible at scrolling. Here, we avoid the * background complete redrawing but the code is a bit * clumsy. */ - if (t->selectedRow() == numberOfRows()-1) { - m_view.reloadBottomRow(this, AppsContainer::sharedAppsContainer()->numberOfApps()-1, k_numberOfColumns); + if (t->selectedRow() == numberOfRows() - 1) { + m_view.reloadBottomRow(this, AppsContainer::sharedAppsContainer()->numberOfApps() - 1, k_numberOfColumns); } } diff --git a/apps/shared/store_selectable_table_view.cpp b/apps/shared/store_selectable_table_view.cpp index 83b086deb..5d547c79d 100644 --- a/apps/shared/store_selectable_table_view.cpp +++ b/apps/shared/store_selectable_table_view.cpp @@ -9,34 +9,35 @@ StoreSelectableTableView::StoreSelectableTableView(DoublePairStore * store, Resp } bool StoreSelectableTableView::handleEvent(Ion::Events::Event event) { + int step = Ion::Events::longRepetitionScrollSpeed(); if (event == Ion::Events::Down) { - return selectNonHiddenCellAtLocation(selectedColumn(), selectedRow()+1); + return selectNonHiddenCellAtClippedLocation(selectedColumn(), selectedRow() + step); } if (event == Ion::Events::Up) { - return selectNonHiddenCellAtLocation(selectedColumn(), selectedRow()-1); + return selectNonHiddenCellAtClippedLocation(selectedColumn(), selectedRow() - step); } if (event == Ion::Events::Left) { - return selectNonHiddenCellAtLocation(selectedColumn()-1, selectedRow()); + return selectNonHiddenCellAtClippedLocation(selectedColumn() - step, selectedRow()); } if (event == Ion::Events::Right) { - return selectNonHiddenCellAtLocation(selectedColumn()+1, selectedRow()); + return selectNonHiddenCellAtClippedLocation(selectedColumn() + step, selectedRow()); } return false; } -bool StoreSelectableTableView::selectNonHiddenCellAtLocation(int i, int j) { - if (i < 0 || i >= dataSource()->numberOfColumns()) { - return false; +bool StoreSelectableTableView::selectNonHiddenCellAtClippedLocation(int i, int j) { + // Clip i to retrieve a valid seriesIndex + if (i < 0) { + i = 0; + } else if (i >= dataSource()->numberOfColumns()) { + i = dataSource()->numberOfColumns() - 1; } - if (j < 0 || j >= dataSource()->numberOfRows()) { - return false; - } - int seriesIndex = i/DoublePairStore::k_numberOfColumnsPerSeries; + int seriesIndex = i / DoublePairStore::k_numberOfColumnsPerSeries; int numberOfPairsOfCurrentSeries = m_store->numberOfPairsOfSeries(seriesIndex); if (j > 1 + numberOfPairsOfCurrentSeries) { - return selectCellAtLocation(i, 1 + numberOfPairsOfCurrentSeries); + j = 1 + numberOfPairsOfCurrentSeries; } - return selectCellAtLocation(i, j); + return selectCellAtClippedLocation(i, j); } } diff --git a/apps/shared/store_selectable_table_view.h b/apps/shared/store_selectable_table_view.h index e8592d831..09efdf101 100644 --- a/apps/shared/store_selectable_table_view.h +++ b/apps/shared/store_selectable_table_view.h @@ -12,7 +12,7 @@ public: StoreSelectableTableView(DoublePairStore * store, Responder * parentResponder, TableViewDataSource * dataSource, SelectableTableViewDataSource * selectionDataSource = nullptr, SelectableTableViewDelegate * delegate = nullptr); bool handleEvent(Ion::Events::Event event) override; private: - bool selectNonHiddenCellAtLocation(int i, int j); + bool selectNonHiddenCellAtClippedLocation(int i, int j); DoublePairStore * m_store; }; diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index 6e4fb7ac0..7e5c30a1a 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -30,6 +30,7 @@ public: void willExitResponderChain(Responder * nextFirstResponder) override; void deselectTable(bool withinTemporarySelection = false); bool selectCellAtLocation(int i, int j, bool setFirstResponder = true, bool withinTemporarySelection = false); + bool selectCellAtClippedLocation(int i, int j, bool setFirstResponder = true, bool withinTemporarySelection = false); HighlightCell * selectedCell(); protected: void unhighlightSelectedCell(); diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index b77f46011..854964760 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -125,6 +125,24 @@ bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstRespon return true; } +bool SelectableTableView::selectCellAtClippedLocation(int i, int j, bool setFirstResponder, bool withinTemporarySelection) { + if (i < 0) { + i = 0; + } else if (i >= dataSource()->numberOfColumns()) { + i = dataSource()->numberOfColumns() - 1; + } + if (j < 0) { + j = 0; + } else if (j >= dataSource()->numberOfRows()) { + j = dataSource()->numberOfRows() - 1; + } + if (j == selectedRow() && i == selectedColumn()) { + // Cell was already selected. + return false; + } + return selectCellAtLocation(i, j, setFirstResponder, withinTemporarySelection); +} + HighlightCell * SelectableTableView::selectedCell() { if (selectedColumn() < 0 || selectedRow() < 0) { return nullptr; @@ -133,17 +151,18 @@ HighlightCell * SelectableTableView::selectedCell() { } bool SelectableTableView::handleEvent(Ion::Events::Event event) { + int step = Ion::Events::longRepetitionScrollSpeed(); if (event == Ion::Events::Down) { - return selectCellAtLocation(selectedColumn(), selectedRow()+1); + return selectCellAtClippedLocation(selectedColumn(), selectedRow() + step); } if (event == Ion::Events::Up) { - return selectCellAtLocation(selectedColumn(), selectedRow()-1); + return selectCellAtClippedLocation(selectedColumn(), selectedRow() - step); } if (event == Ion::Events::Left) { - return selectCellAtLocation(selectedColumn()-1, selectedRow()); + return selectCellAtClippedLocation(selectedColumn() - step, selectedRow()); } if (event == Ion::Events::Right) { - return selectCellAtLocation(selectedColumn()+1, selectedRow()); + return selectCellAtClippedLocation(selectedColumn() + step, selectedRow()); } if (event == Ion::Events::Copy || event == Ion::Events::Cut) { HighlightCell * cell = selectedCell();