From f3eb2b80df8ae214b57ba75d71926391630e31f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 21 Apr 2017 17:36:41 +0200 Subject: [PATCH] [escher] In textField, record edited data when changing selection Change-Id: I74e1cac2188986244f79e7c5ad0eb1d300510475 --- .../edit_expression_controller.cpp | 2 +- apps/calculation/edit_expression_controller.h | 2 +- apps/probability/calculation_controller.cpp | 9 ++- apps/probability/calculation_controller.h | 3 +- apps/probability/parameters_controller.cpp | 4 +- apps/probability/parameters_controller.h | 2 +- .../editable_cell_table_view_controller.cpp | 15 +++- .../editable_cell_table_view_controller.h | 4 +- apps/shared/float_parameter_controller.cpp | 14 +++- apps/shared/float_parameter_controller.h | 4 +- apps/shared/range_parameter_controller.cpp | 4 +- apps/shared/range_parameter_controller.h | 2 +- apps/shared/text_field_delegate.cpp | 4 ++ apps/shared/text_field_delegate.h | 1 + apps/shared/text_field_delegate_app.cpp | 6 +- apps/shared/text_field_delegate_app.h | 1 + escher/include/escher/input_view_controller.h | 3 +- escher/include/escher/text_field.h | 1 + escher/include/escher/text_field_delegate.h | 3 +- escher/src/input_view_controller.cpp | 6 +- escher/src/text_field.cpp | 72 +++++++++---------- 21 files changed, 102 insertions(+), 60 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 5204515ef..de834d0c6 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -77,7 +77,7 @@ void EditExpressionController::didBecomeFirstResponder() { app()->setFirstResponder(((ContentView *)view())->textField()); } -bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text) { +bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) { App * calculationApp = (App *)app(); m_calculationStore->push(textBody(), calculationApp->localContext()); m_historyController->reload(); diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index e4b9ea151..82b80ee33 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -17,7 +17,7 @@ public: bool handleEvent(Ion::Events::Event event) override; const char * textBody(); void setTextBody(const char * text); - bool textFieldDidFinishEditing(::TextField * textField, const char * text) override; + bool textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) override; bool textFieldDidAbortEditing(::TextField * textField, const char * text) override; void loadView() override; void unloadView() override; diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index ea53b9c65..4e471f755 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -211,7 +211,11 @@ bool CalculationController::handleEvent(Ion::Events::Event event) { return false; } -bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text) { +bool CalculationController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return (event == Ion::Events::Right && m_highlightedSubviewIndex < ContentView::k_maxNumberOfEditableFields - 1) || event == Ion::Events::Left || TextFieldDelegate::textFieldShouldFinishEditing(textField, event); +} + +bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { App * probaApp = (App *)app(); Context * globalContext = probaApp->container()->globalContext(); float floatBody = Expression::parse(text)->approximate(*globalContext); @@ -231,6 +235,9 @@ bool CalculationController::textFieldDidFinishEditing(TextField * textField, con floatBody = roundf(floatBody); } m_calculation->setParameterAtIndex(floatBody, m_highlightedSubviewIndex-1); + if (event == Ion::Events::Right || event == Ion::Events::Left) { + handleEvent(event); + } for (int k = 0; k < m_calculation->numberOfParameters(); k++) { m_contentView.willDisplayEditableCellAtIndex(k); } diff --git a/apps/probability/calculation_controller.h b/apps/probability/calculation_controller.h index 6ec692b5b..371f72aca 100644 --- a/apps/probability/calculation_controller.h +++ b/apps/probability/calculation_controller.h @@ -21,7 +21,8 @@ public: bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; void selectSubview(int subviewIndex); - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; private: void updateTitle(); diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index 2e0d627c0..c15405862 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -152,8 +152,8 @@ bool ParametersController::setParameterAtIndex(int parameterIndex, float f) { return true; } -bool ParametersController::textFieldDidFinishEditing(TextField * textField, const char * text) { - if (FloatParameterController::textFieldDidFinishEditing(textField, text)) { +bool ParametersController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { + if (FloatParameterController::textFieldDidFinishEditing(textField, text, event)) { m_selectableTableView->reloadData(); return true; } diff --git a/apps/probability/parameters_controller.h b/apps/probability/parameters_controller.h index b50cdc393..27f392ce2 100644 --- a/apps/probability/parameters_controller.h +++ b/apps/probability/parameters_controller.h @@ -24,7 +24,7 @@ private: float previousParameterAtIndex(int index) override; float parameterAtIndex(int index) override; bool setParameterAtIndex(int parameterIndex, float f) override; - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; I18n::Message okButtonText() override; View * createView() override; class ContentView : public View { diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index a5f92145a..f3e91a1e2 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -14,7 +14,14 @@ EditableCellTableViewController::EditableCellTableViewController(Responder * par { } -bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text) { +bool EditableCellTableViewController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return TextFieldDelegate::textFieldShouldFinishEditing(textField, event) + || (event == Ion::Events::Down && selectableTableView()->selectedRow() < numberOfRows()-1) + || (event == Ion::Events::Up && selectableTableView()->selectedRow() > 0) + || (event == Ion::Events::Right && selectableTableView()->selectedColumn() < numberOfColumns()-1) + || (event == Ion::Events::Left && selectableTableView()->selectedColumn() > 0); } + +bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); float floatBody = Expression::parse(text)->approximate(*globalContext); @@ -27,7 +34,11 @@ bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * text return false; } selectableTableView()->reloadData(); - selectableTableView()->selectCellAtLocation(selectableTableView()->selectedColumn(), selectableTableView()->selectedRow()+1); + if (event == Ion::Events::EXE || event == Ion::Events::OK) { + selectableTableView()->selectCellAtLocation(selectableTableView()->selectedColumn(), selectableTableView()->selectedRow()+1); + } else { + selectableTableView()->handleEvent(event); + } return true; } diff --git a/apps/shared/editable_cell_table_view_controller.h b/apps/shared/editable_cell_table_view_controller.h index 6518207dd..2a66dd554 100644 --- a/apps/shared/editable_cell_table_view_controller.h +++ b/apps/shared/editable_cell_table_view_controller.h @@ -13,8 +13,8 @@ class EditableCellTableViewController : public TabTableController , public Regul public: EditableCellTableViewController(Responder * parentResponder, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin); - - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + 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; int numberOfRows() override; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 646b1c1c9..5c0860f2f 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -112,7 +112,13 @@ void FloatParameterController::willDisplayCellForIndex(HighlightCell * cell, int myCell->setAccessoryText(buffer); } -bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, const char * text) { +bool FloatParameterController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return (event == Ion::Events::Down && selectableTableView()->selectedRow() < numberOfRows()-1) + || (event == Ion::Events::Up && selectableTableView()->selectedRow() > 0) + || TextFieldDelegate::textFieldShouldFinishEditing(textField, event); +} + +bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); float floatBody = Expression::parse(text)->approximate(*globalContext); @@ -126,7 +132,11 @@ bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, willDisplayCellForIndex(selectableTableView()->cellAtLocation(selectableTableView()->selectedColumn(), selectableTableView()->selectedRow()), activeCell()); selectableTableView()->reloadData(); - selectableTableView()->selectCellAtLocation(selectableTableView()->selectedColumn(), selectableTableView()->selectedRow()+1); + if (event == Ion::Events::EXE || event == Ion::Events::OK) { + selectableTableView()->selectCellAtLocation(selectableTableView()->selectedColumn(), selectableTableView()->selectedRow()+1); + } else { + selectableTableView()->handleEvent(event); + } return true; } diff --git a/apps/shared/float_parameter_controller.h b/apps/shared/float_parameter_controller.h index dddf1f9e8..5f848760e 100644 --- a/apps/shared/float_parameter_controller.h +++ b/apps/shared/float_parameter_controller.h @@ -25,8 +25,8 @@ public: KDCoordinate cumulatedHeightFromIndex(int j) override; int indexFromCumulatedHeight(KDCoordinate offsetY) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; - - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; void unloadView() override; diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index bbde23380..57c3b23f5 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -58,8 +58,8 @@ void RangeParameterController::willDisplayCellForIndex(HighlightCell * cell, int FloatParameterController::willDisplayCellForIndex(cell, index); } -bool RangeParameterController::textFieldDidFinishEditing(TextField * textField, const char * text) { - if (FloatParameterController::textFieldDidFinishEditing(textField, text)) { +bool RangeParameterController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { + if (FloatParameterController::textFieldDidFinishEditing(textField, text, event)) { selectableTableView()->reloadData(); return true; } diff --git a/apps/shared/range_parameter_controller.h b/apps/shared/range_parameter_controller.h index 1bb94293d..b885a06bf 100644 --- a/apps/shared/range_parameter_controller.h +++ b/apps/shared/range_parameter_controller.h @@ -15,7 +15,7 @@ public: int numberOfRows() override; int typeAtLocation(int i, int j) override; void willDisplayCellForIndex(HighlightCell * cell, int index) override; - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; bool handleEvent(Ion::Events::Event event) override; void unloadView() override; diff --git a/apps/shared/text_field_delegate.cpp b/apps/shared/text_field_delegate.cpp index 0b00392d2..907ef9ca6 100644 --- a/apps/shared/text_field_delegate.cpp +++ b/apps/shared/text_field_delegate.cpp @@ -4,6 +4,10 @@ using namespace Poincare; namespace Shared { +bool TextFieldDelegate::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return textFieldDelegateApp()->textFieldShouldFinishEditing(textField, event); +} + bool TextFieldDelegate::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) { return textFieldDelegateApp()->textFieldDidReceiveEvent(textField, event); } diff --git a/apps/shared/text_field_delegate.h b/apps/shared/text_field_delegate.h index 9159970ea..aeab2045d 100644 --- a/apps/shared/text_field_delegate.h +++ b/apps/shared/text_field_delegate.h @@ -9,6 +9,7 @@ namespace Shared { class TextFieldDelegate : public ::TextFieldDelegate { public: + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; Toolbox * toolboxForTextField(TextField * textField) override; private: diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index b66174b49..e0da49af5 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -46,8 +46,12 @@ bool TextFieldDelegateApp::cursorInToken(TextField * textField, const char * tok return false; } +bool TextFieldDelegateApp::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return event == Ion::Events::OK || event == Ion::Events::EXE; +} + bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { - if ((event == Ion::Events::OK || event == Ion::Events::EXE) && textField->isEditing()) { + if (textField->textFieldShouldFinishEditing(event) && textField->isEditing()) { Expression * exp = Expression::parse(textField->text()); if (exp == nullptr || !exp->hasValidNumberOfArguments()) { if (textField->textLength() == 0) { diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index 71741dd9e..2f1972320 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -14,6 +14,7 @@ public: virtual Poincare::Context * localContext(); AppsContainer * container(); virtual const char * XNT(); + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; Toolbox * toolboxForTextField(TextField * textField) override; private: diff --git a/escher/include/escher/input_view_controller.h b/escher/include/escher/input_view_controller.h index 864b242e4..8085a8c06 100644 --- a/escher/include/escher/input_view_controller.h +++ b/escher/include/escher/input_view_controller.h @@ -13,7 +13,8 @@ public: const char * textBody(); bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; void abortTextFieldEditionAndDismiss(); - bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; bool textFieldDidAbortEditing(TextField * textField, const char * text) override; Toolbox * toolboxForTextField(TextField * textFied) override; private: diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index f4631f386..8f41c4c6b 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -29,6 +29,7 @@ public: KDSize minimalSizeForOptimalDisplay() const override; void setTextFieldDelegate(TextFieldDelegate * delegate); bool handleEvent(Ion::Events::Event event) override; + bool textFieldShouldFinishEditing(Ion::Events::Event event); constexpr static int maxBufferSize() { return ContentView::k_maxBufferSize; } diff --git a/escher/include/escher/text_field_delegate.h b/escher/include/escher/text_field_delegate.h index a9fcc3404..c750836e1 100644 --- a/escher/include/escher/text_field_delegate.h +++ b/escher/include/escher/text_field_delegate.h @@ -5,8 +5,9 @@ class TextField; class TextFieldDelegate { public: + virtual bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) = 0; virtual bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) = 0; - virtual bool textFieldDidFinishEditing(TextField * textField, const char * text) {return false;}; + virtual bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) {return false;}; virtual bool textFieldDidAbortEditing(TextField * textField, const char * text) {return false;}; virtual Toolbox * toolboxForTextField(TextField * textFied) = 0; }; diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index 35b05003d..46efbde3a 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -86,7 +86,11 @@ void InputViewController::abortTextFieldEditionAndDismiss() { dismissModalViewController(); } -bool InputViewController::textFieldDidFinishEditing(TextField * textField, const char * text) { +bool InputViewController::textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) { + return event == Ion::Events::OK || event == Ion::Events::EXE; +} + +bool InputViewController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { m_successAction.perform(this); dismissModalViewController(); return true; diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index f121dcacc..ad57474bf 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -271,56 +271,52 @@ void TextField::setTextFieldDelegate(TextFieldDelegate * delegate) { m_delegate = delegate; } +bool TextField::textFieldShouldFinishEditing(Ion::Events::Event event) { + return m_delegate->textFieldShouldFinishEditing(this, event); +} + bool TextField::handleEvent(Ion::Events::Event event) { + assert(m_delegate != nullptr); if (Responder::handleEvent(event)) { return true; } - if (m_delegate) { - if (m_delegate->textFieldDidReceiveEvent(this, event)) { - return true; - } + if (m_delegate->textFieldDidReceiveEvent(this, event)) { + return true; } - if (event == Ion::Events::OK || event == Ion::Events::EXE) { - if (isEditing()) { - char bufferText[ContentView::k_maxBufferSize]; - strlcpy(bufferText, m_contentView.textBuffer(), ContentView::k_maxBufferSize); - strlcpy(m_contentView.textBuffer(), m_contentView.draftTextBuffer(), m_contentView.bufferSize()); - int cursorLoc = cursorLocation(); - setEditing(false, m_hasTwoBuffers); - if (m_delegate->textFieldDidFinishEditing(this, text())) { - reloadScroll(); - return true; - } - /* if the text was refused (textFieldDidFinishEditing returned false, we - * reset the textfield in the same state as before */ - char bufferDraft[ContentView::k_maxBufferSize]; - strlcpy(bufferDraft, m_contentView.textBuffer(), ContentView::k_maxBufferSize); - setText(bufferText); - setEditing(true); - setText(bufferDraft); - setCursorLocation(cursorLoc); + if (event == Ion::Events::Left && isEditing() && cursorLocation() > 0) { + setCursorLocation(cursorLocation()-1); + return true; + } + if (event == Ion::Events::Right && isEditing() && cursorLocation() < textLength()) { + setCursorLocation(cursorLocation()+1); + return true; + } + if (textFieldShouldFinishEditing(event) && isEditing()) { + char bufferText[ContentView::k_maxBufferSize]; + strlcpy(bufferText, m_contentView.textBuffer(), ContentView::k_maxBufferSize); + strlcpy(m_contentView.textBuffer(), m_contentView.draftTextBuffer(), m_contentView.bufferSize()); + int cursorLoc = cursorLocation(); + setEditing(false, m_hasTwoBuffers); + if (m_delegate->textFieldDidFinishEditing(this, text(), event)) { + reloadScroll(); return true; } - if (event == Ion::Events::EXE) { - return false; - } + /* if the text was refused (textFieldDidFinishEditing returned false, we + * reset the textfield in the same state as before */ + char bufferDraft[ContentView::k_maxBufferSize]; + strlcpy(bufferDraft, m_contentView.textBuffer(), ContentView::k_maxBufferSize); + setText(bufferText); + setEditing(true); + setText(bufferDraft); + setCursorLocation(cursorLoc); + return true; + } + if (event == Ion::Events::OK) { setEditing(true); insertTextAtLocation(m_contentView.textBuffer(), cursorLocation()); setCursorLocation(strlen(m_contentView.draftTextBuffer())); return true; } - if (event == Ion::Events::Left && isEditing()) { - if (cursorLocation() > 0) { - setCursorLocation(cursorLocation()-1); - } - return true; - } - if (event == Ion::Events::Right && isEditing()) { - if (cursorLocation() < textLength()) { - setCursorLocation(cursorLocation()+1); - } - return true; - } if (event == Ion::Events::Backspace && isEditing()) { deleteCharPrecedingCursor(); layoutSubviews();