[escher/expression_field] Detect whether view's height did change by memoizing the height

Such changes used to be detected only when the height was equal to the
maximal allowed value, by detecting whether the height shifted from or
to that maximal value. For that purpose, a boolean was memoized in
InputViewController and in Calculation::EditExpressionController.
This commit is contained in:
Ruben Dashyan
2019-10-10 16:42:25 +02:00
committed by Léa Saviot
parent 40d75ffefa
commit 7fce83d1dd
6 changed files with 21 additions and 19 deletions

View File

@@ -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

View File

@@ -53,7 +53,6 @@ private:
HistoryController * m_historyController;
CalculationStore * m_calculationStore;
ContentView m_contentView;
bool m_inputViewHeightIsMaximal;
};
}

View File

@@ -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;
};

View File

@@ -64,7 +64,6 @@ private:
InputEventHandlerDelegate * m_inputEventHandlerDelegate;
TextFieldDelegate * m_textFieldDelegate;
LayoutFieldDelegate * m_layoutFieldDelegate;
bool m_inputViewHeightIsMaximal;
};
#endif

View File

@@ -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) {

View File

@@ -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