From 5d8256435edd4bd8c9fa9fce17b40b48c13ea5af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 23 Jan 2018 15:10:13 +0100 Subject: [PATCH] [apps] Probability: fix bug; in calculation controller, when reloading cells after editing textfield, do not reload selection (it corrupts the responder chain if the first reponder was a modal view for ex) --- apps/probability/calculation_controller.cpp | 6 ++++- escher/include/escher/selectable_table_view.h | 4 +-- escher/src/selectable_table_view.cpp | 26 ++++++++----------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index f9f55ca6c..d2b3835ba 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -206,7 +206,11 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int bool CalculationController::textFieldDidHandleEvent(::TextField * textField, Ion::Events::Event event, bool returnValue, bool textHasChanged) { if (returnValue && textHasChanged) { - m_selectableTableView.reloadData(); //TODO: optimize with reloadCell at index? + /* We do not reload the responder because the first responder might be the + * toolbox (or the variable box) and reloading the responder would corrupt + * the first responder. */ + bool shouldUpdateFirstResponder = app()->firstResponder() == textField; + m_selectableTableView.reloadData(shouldUpdateFirstResponder); } return returnValue; } diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index 3b89760e3..f6453db29 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -27,12 +27,12 @@ public: int selectedColumn(); void selectRow(int j); void selectColumn(int i); - void reloadData(bool reloadSelection = true); + void reloadData(bool setFirstResponder = true); virtual bool handleEvent(Ion::Events::Event event) override; virtual void didEnterResponderChain(Responder * previousFirstResponder) override; virtual void willExitResponderChain(Responder * nextFirstResponder) override; void deselectTable(); - bool selectCellAtLocation(int i, int j); + bool selectCellAtLocation(int i, int j, bool setFirstResponder = true); HighlightCell * selectedCell(); protected: SelectableTableViewDataSource * m_selectionDataSource; diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index 5561d5ded..f732b5446 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -29,22 +29,18 @@ void SelectableTableView::selectColumn(int i) { m_selectionDataSource->selectColumn(i); } -void SelectableTableView::reloadData(bool reloadSelection) { +void SelectableTableView::reloadData(bool setFirstResponder) { int col = selectedColumn(); int row = selectedRow(); - if (reloadSelection) { - deselectTable(); - /* 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 - * order to deselect it). */ - /* As a workaround, datasources can reset the highlighted state in their - * willDisplayCell callback. */ - } + deselectTable(); + /* 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 + * order to deselect it). */ + /* As a workaround, datasources can reset the highlighted state in their + * willDisplayCell callback. */ TableView::layoutSubviews(); - if (reloadSelection) { - selectCellAtLocation(col, row); - } + selectCellAtLocation(col, row, setFirstResponder); } void SelectableTableView::didEnterResponderChain(Responder * previousFirstResponder) { @@ -70,7 +66,7 @@ void SelectableTableView::deselectTable() { } } -bool SelectableTableView::selectCellAtLocation(int i, int j) { +bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstResponder) { if (i < 0 || i >= dataSource()->numberOfColumns()) { return false; } @@ -89,7 +85,7 @@ bool SelectableTableView::selectCellAtLocation(int i, int j) { if (cell) { cell->setHighlighted(true); // Update first responder - if (i != previousX || j != previousY) { + if ((i != previousX || j != previousY) && setFirstResponder) { if (cell->responder()) { app()->setFirstResponder(cell->responder()); } else {