diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 41a63a854..df76015ab 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -42,8 +42,7 @@ EditExpressionController::EditExpressionController(Responder * parentResponder, ViewController(parentResponder), m_historyController(historyController), m_calculationStore(calculationStore), - m_contentView(this, (TableView *)m_historyController->view(), inputEventHandlerDelegate, this, this), - m_inputViewHeightIsMaximal(false) + m_contentView(this, (TableView *)m_historyController->view(), inputEventHandlerDelegate, this, this) { m_cacheBuffer[0] = 0; } @@ -90,11 +89,9 @@ bool EditExpressionController::layoutFieldDidAbortEditing(::LayoutField * layout } void EditExpressionController::layoutFieldDidChangeSize(::LayoutField * layoutField) { - /* Reload the view only if the ExpressionField height actually changes, i.e. - * not if the height is already maximal and stays maximal. */ - bool newInputViewHeightIsMaximal = m_contentView.expressionField()->heightIsMaximal(); - if (!m_inputViewHeightIsMaximal || !newInputViewHeightIsMaximal) { - m_inputViewHeightIsMaximal = newInputViewHeightIsMaximal; + if (m_contentView.expressionField()->inputViewHeightDidChange()) { + /* Reload the whole view only if the ExpressionField's height did actually + * change. */ reloadView(); } else { /* The input view is already at maximal size so we do not need to relayout diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index 42c949323..0259f8795 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -53,7 +53,6 @@ private: HistoryController * m_historyController; CalculationStore * m_calculationStore; ContentView m_contentView; - bool m_inputViewHeightIsMaximal; }; } diff --git a/escher/include/escher/expression_field.h b/escher/include/escher/expression_field.h index 6e3faf5b2..bdbec1afa 100644 --- a/escher/include/escher/expression_field.h +++ b/escher/include/escher/expression_field.h @@ -23,7 +23,7 @@ public: void setText(const char * text); bool editionIsInTextField() const; bool isEmpty() const; - bool heightIsMaximal() const; + bool inputViewHeightDidChange(); bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false); /* View */ @@ -35,6 +35,7 @@ public: /* Responder */ bool handleEvent(Ion::Events::Event event) override; + void didBecomeFirstResponder() override; private: static constexpr int k_textFieldBufferSize = TextField::maxBufferSize(); @@ -44,6 +45,7 @@ private: static constexpr KDCoordinate k_verticalMargin = 5; constexpr static KDCoordinate k_separatorThickness = Metric::CellSeparatorThickness; KDCoordinate inputViewHeight() const; + KDCoordinate m_inputViewMemoizedHeight; TextField m_textField; LayoutField m_layoutField; }; diff --git a/escher/include/escher/input_view_controller.h b/escher/include/escher/input_view_controller.h index 2867c6959..5d0bd9197 100644 --- a/escher/include/escher/input_view_controller.h +++ b/escher/include/escher/input_view_controller.h @@ -64,7 +64,6 @@ private: InputEventHandlerDelegate * m_inputEventHandlerDelegate; TextFieldDelegate * m_textFieldDelegate; LayoutFieldDelegate * m_layoutFieldDelegate; - bool m_inputViewHeightIsMaximal; }; #endif diff --git a/escher/src/expression_field.cpp b/escher/src/expression_field.cpp index fb8fcf7df..9c7dbab8a 100644 --- a/escher/src/expression_field.cpp +++ b/escher/src/expression_field.cpp @@ -8,6 +8,7 @@ static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { retur ExpressionField::ExpressionField(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) : Responder(parentResponder), View(), + m_inputViewMemoizedHeight(0), m_textField(parentResponder, nullptr, k_textFieldBufferSize, k_textFieldBufferSize, inputEventHandlerDelegate, textFieldDelegate, KDFont::LargeFont, 0.0f, 0.5f, KDColorBlack, KDColorWhite), m_layoutField(parentResponder, inputEventHandlerDelegate, layoutFieldDelegate) { @@ -82,6 +83,10 @@ bool ExpressionField::handleEvent(Ion::Events::Event event) { return editionIsInTextField() ? m_textField.handleEvent(event) : m_layoutField.handleEvent(event); } +void ExpressionField::didBecomeFirstResponder() { + m_inputViewMemoizedHeight = inputViewHeight(); +} + KDSize ExpressionField::minimalSizeForOptimalDisplay() const { return KDSize(0, inputViewHeight()); } @@ -94,8 +99,11 @@ bool ExpressionField::isEmpty() const { return editionIsInTextField() ? (m_textField.draftTextLength() == 0) : !m_layoutField.hasText(); } -bool ExpressionField::heightIsMaximal() const { - return inputViewHeight() == k_separatorThickness + k_maximalHeight; +bool ExpressionField::inputViewHeightDidChange() { + KDCoordinate newHeight = inputViewHeight(); + bool didChange = m_inputViewMemoizedHeight != newHeight; + m_inputViewMemoizedHeight = newHeight; + return didChange; } bool ExpressionField::handleEventWithText(const char * text, bool indentation, bool forceCursorRightOfText) { diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index 669c7e60c..2947054a7 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -20,8 +20,7 @@ InputViewController::InputViewController(Responder * parentResponder, ViewContro m_failureAction(Invocation(nullptr, nullptr)), m_inputEventHandlerDelegate(inputEventHandlerDelegate), m_textFieldDelegate(textFieldDelegate), - m_layoutFieldDelegate(layoutFieldDelegate), - m_inputViewHeightIsMaximal(false) + m_layoutFieldDelegate(layoutFieldDelegate) { } @@ -86,11 +85,9 @@ bool InputViewController::layoutFieldDidAbortEditing(LayoutField * layoutField) } void InputViewController::layoutFieldDidChangeSize(LayoutField * layoutField) { - /* Reload the view only if the ExpressionField height actually changes, i.e. - * not if the height is already maximal and stays maximal. */ - bool newInputViewHeightIsMaximal = m_expressionFieldController.expressionField()->heightIsMaximal(); - if (!m_inputViewHeightIsMaximal || !newInputViewHeightIsMaximal) { - m_inputViewHeightIsMaximal = newInputViewHeightIsMaximal; + if (m_expressionFieldController.expressionField()->inputViewHeightDidChange()) { + /* Reload the whole view only if the ExpressionField's height did actually + * change. */ reloadModalViewController(); } else { /* The input view is already at maximal size so we do not need to relayout