[escher] SelectableTableView: when reloading data, we temporary deselect

the table. We warn the SelectableTableViewDelegate that the selection
change is 'within a temporary selection change' when notifying it of the
change.
This commit is contained in:
Émilie Feral
2019-04-26 14:48:31 +02:00
parent 138587ee8e
commit 2217eebaec
20 changed files with 48 additions and 34 deletions

View File

@@ -105,8 +105,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) {
return false;
}
void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
if (previousSelectedCellY == selectedRow()) {
void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection || previousSelectedCellY == selectedRow()) {
return;
}
HistoryViewCell * cell = static_cast<HistoryViewCell *>(t->selectedCell());

View File

@@ -24,7 +24,7 @@ public:
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
KDCoordinate rowHeight(int j) override;
int typeAtLocation(int i, int j) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false) override;
void scrollToCell(int i, int j);
private:
CalculationSelectableTableView * selectableTableView();

View File

@@ -245,7 +245,10 @@ void ConsoleController::willDisplayCellAtLocation(HighlightCell * cell, int i, i
}
}
void ConsoleController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void ConsoleController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection) {
return;
}
if (t->selectedRow() == m_consoleStore.numberOfLines()) {
m_editCell.setEditing(true);
return;

View File

@@ -52,7 +52,7 @@ public:
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
// SelectableTableViewDelegate
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
// TextFieldDelegate
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;

View File

@@ -272,8 +272,8 @@ void MenuController::willDisplayScriptTitleCellForIndex(HighlightCell * cell, in
(static_cast<ScriptNameCell *>(cell))->textField()->setText(m_scriptStore->scriptAtIndex(index).fullName());
}
void MenuController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
if (selectedRow() == numberOfRows() - 1 && selectedColumn() == 1 && m_shouldDisplayAddScriptRow) {
void MenuController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (!withinTemporarySelection && selectedRow() == numberOfRows() - 1 && selectedColumn() == 1 && m_shouldDisplayAddScriptRow) {
t->selectCellAtLocation(0, numberOfRows()-1);
}
}

View File

@@ -46,7 +46,7 @@ public:
void willDisplayScriptTitleCellForIndex(HighlightCell * cell, int index);
/* SelectableTableViewDelegate */
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
/* TextFieldDelegate */
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;

View File

@@ -134,7 +134,10 @@ int Controller::numberOfIcons() {
return m_container->numberOfApps() - 1;
}
void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection) {
return;
}
/* If the number of apps (including home) is != 3*n+1, when we display the
* lowest icons, the other(s) are empty. As no icon is thus redrawn on the
* previous ones, the cell is not cleaned. We need to redraw a white rect on

View File

@@ -25,7 +25,7 @@ public:
virtual HighlightCell * reusableCell(int index) override;
virtual int reusableCellCount() override;
void willDisplayCellAtLocation(HighlightCell * cell, int i, int j) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
private:
int numberOfIcons();
class ContentView : public View {

View File

@@ -65,7 +65,10 @@ void CalculationController::didBecomeFirstResponder() {
TabTableController::didBecomeFirstResponder();
}
void CalculationController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void CalculationController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection) {
return;
}
/* To prevent selecting cell with no content (top left corner of the table),
* as soon as the selected cell is the top left corner, we either reselect
* the previous cell or select the tab controller depending on from which cell

View File

@@ -29,7 +29,7 @@ public:
void didBecomeFirstResponder() override;
// SelectableTableViewDelegate
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
// AlternateEmptyViewDefaultDelegate
bool isEmpty() const override;

View File

@@ -92,8 +92,8 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c
return true;
}
void ListParameterController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
if (previousSelectedCellX == t->selectedColumn() && previousSelectedCellY == t->selectedRow()) {
void ListParameterController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
if (withinTemporarySelection || (previousSelectedCellX == t->selectedColumn() && previousSelectedCellY == t->selectedRow())) {
return;
}
if (!hasInitialRankRow()) {

View File

@@ -19,7 +19,7 @@ public:
bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override;
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
Shared::TextFieldDelegateApp * textFieldDelegateApp() override;
// ListViewDataSource

View File

@@ -16,11 +16,11 @@ ExpressionModelListController::ExpressionModelListController(Responder * parentR
m_addNewModel.setMessage(text);
}
void ExpressionModelListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void ExpressionModelListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
int currentSelectedRow = selectedRow();
// Update m_cumulatedHeightForSelectedIndex if we scrolled one cell up/down
if (previousSelectedCellY >= 0 && previousSelectedCellY == previousSelectedCellY + 1) {
if (currentSelectedRow >= 0 && currentSelectedRow == previousSelectedCellY + 1) {
/* We selected the cell under the previous cell. Shift the memoized cell
* heights. */
shiftMemoization(true);

View File

@@ -13,7 +13,7 @@ public:
protected:
static constexpr KDCoordinate k_expressionMargin = 5;
// SelectableTableViewDelegate
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
// TableViewDataSource
virtual int numberOfExpressionRows();
KDCoordinate memoizedRowHeight(int j);

View File

@@ -214,11 +214,11 @@ void FunctionListController::willExitResponderChain(Responder * nextFirstRespond
/* SelectableTableViewDelegate */
void FunctionListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void FunctionListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
// Update memoization of cell heights
ExpressionModelListController::tableViewDidChangeSelection(t, previousSelectedCellX, previousSelectedCellY);
ExpressionModelListController::tableViewDidChangeSelection(t, previousSelectedCellX, previousSelectedCellY, withinTemporarySelection);
// Do not select the cell left of the "addEmptyFunction" cell
if (isAddEmptyRow(selectedRow()) && selectedColumn() == 0) {
if (!withinTemporarySelection && isAddEmptyRow(selectedRow()) && selectedColumn() == 0) {
t->selectCellAtLocation(1, numberOfRows()-1);
}
}

View File

@@ -45,7 +45,7 @@ public:
View * view() override { return &m_selectableTableView; }
/* SelectableTableViewDelegate*/
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override;
void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override;
/* ExpressionModelListController */
SelectableTableView * selectableTableView() override { return &m_selectableTableView; }

View File

@@ -29,8 +29,8 @@ public:
virtual bool handleEvent(Ion::Events::Event event) override;
virtual void didEnterResponderChain(Responder * previousFirstResponder) override;
virtual void willExitResponderChain(Responder * nextFirstResponder) override;
void deselectTable(bool notifySelectableDelegate = true);
bool selectCellAtLocation(int i, int j, bool setFirstResponder = true, bool notifySelectableDelegate = true);
void deselectTable(bool withinTemporarySelection = false);
bool selectCellAtLocation(int i, int j, bool setFirstResponder = true, bool withinTemporarySelection = false);
HighlightCell * selectedCell();
protected:
SelectableTableViewDataSource * m_selectionDataSource;

View File

@@ -5,7 +5,12 @@ class SelectableTableView;
class SelectableTableViewDelegate {
public:
virtual void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY);
/* withinTemporarySelection flag indicates when the selection change happens
* in a temporary deselection: indeed, when reloading the data of the table,
* we deselect the table before re-layouting the entire table and re-select
* the previous selected cell. We might implement different course of action
* when the selection change is 'real' or within temporary selection. */
virtual void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection = false);
};
#endif

View File

@@ -37,7 +37,7 @@ void SelectableTableView::selectColumn(int i) {
void SelectableTableView::reloadData(bool setFirstResponder) {
int col = selectedColumn();
int row = selectedRow();
deselectTable(false);
deselectTable(true);
/* FIXME: The problem with calling deselectTable is that at this point in time
* the datasource's model is very likely to have changed. Therefore it's
* rather complicated to get a pointer to the currently selected cell (in
@@ -45,7 +45,7 @@ void SelectableTableView::reloadData(bool setFirstResponder) {
/* As a workaround, datasources can reset the highlighted state in their
* willDisplayCell callback. */
TableView::layoutSubviews();
selectCellAtLocation(col, row, setFirstResponder, false);
selectCellAtLocation(col, row, setFirstResponder, true);
}
void SelectableTableView::didEnterResponderChain(Responder * previousFirstResponder) {
@@ -60,18 +60,18 @@ void SelectableTableView::willExitResponderChain(Responder * nextFirstResponder)
unhighlightSelectedCell();
}
void SelectableTableView::deselectTable(bool notifySelectableDelegate) {
void SelectableTableView::deselectTable(bool withinTemporarySelection) {
unhighlightSelectedCell();
int previousSelectedCellX = selectedColumn();
int previousSelectedCellY = selectedRow();
selectColumn(0);
selectRow(-1);
if (m_delegate && notifySelectableDelegate) {
m_delegate->tableViewDidChangeSelection(this, previousSelectedCellX, previousSelectedCellY);
if (m_delegate) {
m_delegate->tableViewDidChangeSelection(this, previousSelectedCellX, previousSelectedCellY, withinTemporarySelection);
}
}
bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstResponder, bool notifySelectableDelegate) {
bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstResponder, bool withinTemporarySelection) {
if (i < 0 || i >= dataSource()->numberOfColumns()) {
return false;
}
@@ -84,8 +84,8 @@ bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstRespon
selectColumn(i);
selectRow(j);
if (m_delegate && notifySelectableDelegate) {
m_delegate->tableViewDidChangeSelection(this, previousX, previousY);
if (m_delegate) {
m_delegate->tableViewDidChangeSelection(this, previousX, previousY, withinTemporarySelection);
}
/* We need to scroll:

View File

@@ -1,4 +1,4 @@
#include <escher/selectable_table_view_delegate.h>
void SelectableTableViewDelegate::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) {
void SelectableTableViewDelegate::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) {
}