mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[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:
committed by
Léa Saviot
parent
40d75ffefa
commit
7fce83d1dd
@@ -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
|
||||
|
||||
@@ -53,7 +53,6 @@ private:
|
||||
HistoryController * m_historyController;
|
||||
CalculationStore * m_calculationStore;
|
||||
ContentView m_contentView;
|
||||
bool m_inputViewHeightIsMaximal;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -64,7 +64,6 @@ private:
|
||||
InputEventHandlerDelegate * m_inputEventHandlerDelegate;
|
||||
TextFieldDelegate * m_textFieldDelegate;
|
||||
LayoutFieldDelegate * m_layoutFieldDelegate;
|
||||
bool m_inputViewHeightIsMaximal;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user