diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index f5c695662..e3707da8f 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -12,8 +12,14 @@ namespace Calculation { EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : View(), m_mainView(subview), - m_expressionField(parentResponder, textFieldDelegate, expressionLayoutFieldDelegate) + m_expressionField(parentResponder, m_textBody, k_bufferLength, m_layout, textFieldDelegate, expressionLayoutFieldDelegate), + m_layout(new Poincare::HorizontalLayout) { + m_textBody[0] = 0; +} + +EditExpressionController::ContentView::~ContentView() { + delete m_layout; } View * EditExpressionController::ContentView::subviewAtIndex(int index) { @@ -93,7 +99,7 @@ bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField) bool EditExpressionController::expressionLayoutFieldDidReceiveEvent(::ExpressionLayoutField * expressionLayoutField, Ion::Events::Event event) { assert(expressionLayoutField == ((ContentView *)view())->expressionField()->expressionLayoutField()); - if (expressionLayoutField->isEditing() && expressionLayoutField->expressionLayoutFieldShouldFinishEditing(event) && !expressionLayout()->hasText() && m_calculationStore->numberOfCalculations() > 0) { + if (expressionLayoutField->isEditing() && expressionLayoutField->expressionLayoutFieldShouldFinishEditing(event) && !expressionLayoutField->hasText() && m_calculationStore->numberOfCalculations() > 0) { return inputViewDidReceiveEvent(event); } return expressionFieldDelegateApp()->expressionLayoutFieldDidReceiveEvent(expressionLayoutField, event); @@ -127,7 +133,6 @@ View * EditExpressionController::loadView() { } void EditExpressionController::unloadView(View * view) { - delete expressionLayout(); delete view; } @@ -176,8 +181,4 @@ void EditExpressionController::viewDidDisappear() { m_historyController->viewDidDisappear(); } -Poincare::ExpressionLayout * EditExpressionController::expressionLayout() { - return ((ContentView *)view())->expressionField()->expressionLayoutField()->expressionLayout(); -} - } diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index def360628..80bbf3b89 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -2,6 +2,7 @@ #define CALCULATION_EDIT_EXPRESSION_CONTROLLER_H #include +#include #include "expression_field.h" #include "../shared/text_field_delegate.h" #include "../shared/expression_layout_field_delegate.h" @@ -36,6 +37,7 @@ private: class ContentView : public View { public: ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate); + ~ContentView(); void reload(); TableView * mainView() { return m_mainView; } ExpressionField * expressionField() { return &m_expressionField; } @@ -44,8 +46,11 @@ private: View * subviewAtIndex(int index) override; void layoutSubviews() override; private: + static constexpr int k_bufferLength = TextField::maxBufferSize(); TableView * m_mainView; ExpressionField m_expressionField; + char m_textBody[k_bufferLength]; + Poincare::ExpressionLayout * m_layout; }; View * loadView() override; void unloadView(View * view) override; @@ -56,7 +61,6 @@ private: Shared::TextFieldDelegateApp * textFieldDelegateApp() override; char m_cacheBuffer[TextField::maxBufferSize()]; Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; - Poincare::ExpressionLayout * expressionLayout(); HistoryController * m_historyController; CalculationStore * m_calculationStore; }; diff --git a/apps/calculation/expression_field.cpp b/apps/calculation/expression_field.cpp index 8a368344a..06ef5d80d 100644 --- a/apps/calculation/expression_field.cpp +++ b/apps/calculation/expression_field.cpp @@ -2,8 +2,8 @@ namespace Calculation { -ExpressionField::ExpressionField(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : - ::ExpressionField(parentResponder, textFieldDelegate, expressionLayoutFieldDelegate) +ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : + ::ExpressionField(parentResponder, textBuffer, textBufferLength, layout, textFieldDelegate, expressionLayoutFieldDelegate) { setEditing(true); } diff --git a/apps/calculation/expression_field.h b/apps/calculation/expression_field.h index 48a069d26..34ba89ace 100644 --- a/apps/calculation/expression_field.h +++ b/apps/calculation/expression_field.h @@ -7,7 +7,7 @@ namespace Calculation { class ExpressionField : public ::ExpressionField { public: - ExpressionField(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate); + ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate); protected: bool handleEvent(Ion::Events::Event event) override; }; diff --git a/escher/include/escher/expression_field.h b/escher/include/escher/expression_field.h index 84807a5a1..d47f11317 100644 --- a/escher/include/escher/expression_field.h +++ b/escher/include/escher/expression_field.h @@ -5,10 +5,11 @@ #include #include #include +#include class ExpressionField : public Responder, public View { public: - ExpressionField(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate); + ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate); void setEditing(bool isEditing, bool reinitDraftBuffer = true); bool isEditing() const; @@ -16,8 +17,6 @@ public: void setText(const char * text); void insertText(const char * text); void reload(); - TextField * textField() { return &m_textField; } - ExpressionLayoutField * expressionLayoutField() { return &m_expressionLayoutField; } bool editionIsInTextField() const; bool isEmpty() const; bool heightIsMaximal() const; @@ -32,7 +31,6 @@ public: /* Responder */ bool handleEvent(Ion::Events::Event event) override; - static constexpr int k_bufferLength = TextField::maxBufferSize(); private: static constexpr KDCoordinate k_textFieldHeight = 37; static constexpr KDCoordinate k_leftMargin = 5; @@ -42,7 +40,8 @@ private: KDCoordinate maximalHeight() const; TextField m_textField; ExpressionLayoutField m_expressionLayoutField; - char m_textBody[k_bufferLength]; + char * m_textBuffer; + int m_textBufferLength; }; #endif diff --git a/escher/include/escher/expression_layout_field.h b/escher/include/escher/expression_layout_field.h index f8f5a412b..76a3cfa48 100644 --- a/escher/include/escher/expression_layout_field.h +++ b/escher/include/escher/expression_layout_field.h @@ -49,6 +49,7 @@ private: Poincare::ExpressionLayoutCursor * cursor() { return &m_cursor; } const ExpressionView * expressionView() const { return &m_expressionView; } ExpressionView * editableExpressionView() { return &m_expressionView; } + void clearLayout(); /* View */ KDSize minimalSizeForOptimalDisplay() const override; private: diff --git a/escher/include/escher/input_view_controller.h b/escher/include/escher/input_view_controller.h index ca8fad4a8..aac58e3bc 100644 --- a/escher/include/escher/input_view_controller.h +++ b/escher/include/escher/input_view_controller.h @@ -41,7 +41,10 @@ private: View * view() override { return &m_expressionField; } ExpressionField * expressionField() { return &m_expressionField; } private: + static constexpr int k_bufferLength = TextField::maxBufferSize(); ExpressionField m_expressionField; + char m_textBuffer[k_bufferLength]; + Poincare::ExpressionLayout * m_layout; }; bool inputViewDidFinishEditing(); bool inputViewDidAbortEditing(); diff --git a/escher/src/expression_field.cpp b/escher/src/expression_field.cpp index ef172771b..cc89fdf05 100644 --- a/escher/src/expression_field.cpp +++ b/escher/src/expression_field.cpp @@ -2,13 +2,14 @@ #include #include -ExpressionField::ExpressionField(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : +ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, int textBufferLength, Poincare::ExpressionLayout * layout, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : Responder(parentResponder), View(), - m_textField(parentResponder, m_textBody, m_textBody, k_bufferLength, textFieldDelegate, false), - m_expressionLayoutField(parentResponder, new Poincare::HorizontalLayout(), expressionLayoutFieldDelegate) + m_textField(parentResponder, textBuffer, textBuffer, textBufferLength, textFieldDelegate, false), + m_expressionLayoutField(parentResponder, layout, expressionLayoutFieldDelegate), + m_textBuffer(textBuffer), + m_textBufferLength(textBufferLength) { - m_textBody[0] = 0; } void ExpressionField::setEditing(bool isEditing, bool reinitDraftBuffer) { @@ -28,9 +29,9 @@ bool ExpressionField::isEditing() const { const char * ExpressionField::text() { if (!editionIsInTextField()) { - m_expressionLayoutField.writeTextInBuffer(m_textBody, k_bufferLength); + m_expressionLayoutField.writeTextInBuffer(m_textBuffer, m_textBufferLength); } - return m_textBody; + return m_textBuffer; } void ExpressionField::setText(const char * text) { diff --git a/escher/src/expression_layout_field.cpp b/escher/src/expression_layout_field.cpp index 712fe52e7..9481ee866 100644 --- a/escher/src/expression_layout_field.cpp +++ b/escher/src/expression_layout_field.cpp @@ -21,10 +21,7 @@ void ExpressionLayoutField::setEditing(bool isEditing) { } void ExpressionLayoutField::clearLayout() { - delete m_contentView.expressionView()->expressionLayout(); - Poincare::ExpressionLayout * newLayout = new Poincare::HorizontalLayout(); - m_contentView.editableExpressionView()->setExpressionLayout(newLayout); - m_contentView.cursor()->setPointedExpressionLayout(newLayout); + m_contentView.clearLayout(); } void ExpressionLayoutField::scrollToCursor() { diff --git a/escher/src/expression_layout_field_content_view.cpp b/escher/src/expression_layout_field_content_view.cpp index f20dcd1ca..1ef370293 100644 --- a/escher/src/expression_layout_field_content_view.cpp +++ b/escher/src/expression_layout_field_content_view.cpp @@ -29,6 +29,10 @@ KDRect ExpressionLayoutField::ContentView::cursorRect() { return m_cursorView.frame(); } +void ExpressionLayoutField::ContentView::clearLayout() { + m_cursor.clearLayout(); +} + KDSize ExpressionLayoutField::ContentView::minimalSizeForOptimalDisplay() const { KDSize expressionViewSize = m_expressionView.minimalSizeForOptimalDisplay(); KDSize cursorSize = isEditing() ? m_cursorView.minimalSizeForOptimalDisplay() : KDSizeZero; diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index a25b3558a..9ee810632 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -6,7 +6,7 @@ InputViewController::ExpressionFieldController::ExpressionFieldController(Responder * parentResponder, TextFieldDelegate * textFieldDelegate, ExpressionLayoutFieldDelegate * expressionLayoutFieldDelegate) : ViewController(parentResponder), - m_expressionField(this, textFieldDelegate, expressionLayoutFieldDelegate) + m_expressionField(this, m_textBuffer, k_bufferLength, m_layout, textFieldDelegate, expressionLayoutFieldDelegate) { } diff --git a/poincare/include/poincare/dynamic_layout_hierarchy.h b/poincare/include/poincare/dynamic_layout_hierarchy.h index 43dbb606e..573e5be64 100644 --- a/poincare/include/poincare/dynamic_layout_hierarchy.h +++ b/poincare/include/poincare/dynamic_layout_hierarchy.h @@ -29,6 +29,7 @@ public: bool addChildAtIndex(ExpressionLayout * operand, int index) override; void removeChildAtIndex(int index, bool deleteAfterRemoval) override; void removePointedChildAtIndexAndMoveCursor(int index, bool deleteAfterRemoval, ExpressionLayoutCursor * cursor) override; + void removeAndDeleteChildren(); virtual void mergeChildrenAtIndex(DynamicLayoutHierarchy * eL, int index, bool removeEmptyChildren); // WITHOUT delete. protected: diff --git a/poincare/include/poincare/expression_layout.h b/poincare/include/poincare/expression_layout.h index d2e94ddda..19d07649e 100644 --- a/poincare/include/poincare/expression_layout.h +++ b/poincare/include/poincare/expression_layout.h @@ -46,6 +46,7 @@ public: const ExpressionLayout * parent() const { return m_parent; } ExpressionLayout * editableParent() { return m_parent; } bool hasAncestor(const ExpressionLayout * e, bool includeSelf = false) const; + ExpressionLayout * editableRoot(); /* Dynamic Layout */ diff --git a/poincare/include/poincare/expression_layout_cursor.h b/poincare/include/poincare/expression_layout_cursor.h index 11ad4a8a9..74719f9b3 100644 --- a/poincare/include/poincare/expression_layout_cursor.h +++ b/poincare/include/poincare/expression_layout_cursor.h @@ -56,6 +56,7 @@ public: void performBackspace(); bool showEmptyLayoutIfNeeded(); bool hideEmptyLayoutIfNeeded(); + void clearLayout(); private: constexpr static KDCoordinate k_cursorHeight = 18; diff --git a/poincare/src/expression_layout_cursor.cpp b/poincare/src/expression_layout_cursor.cpp index 1029a2ef1..e619ffacc 100644 --- a/poincare/src/expression_layout_cursor.cpp +++ b/poincare/src/expression_layout_cursor.cpp @@ -207,6 +207,15 @@ bool ExpressionLayoutCursor::hideEmptyLayoutIfNeeded() { return privateShowHideEmptyLayoutIfNeeded(false); } +void ExpressionLayoutCursor::clearLayout() { + ExpressionLayout * rootLayout = m_pointedExpressionLayout->editableRoot(); + assert(rootLayout->isHorizontal()); + for (int i = 0; i < rootLayout->numberOfChildren(); i++) { + static_cast(rootLayout)->removeAndDeleteChildren(); + } + m_pointedExpressionLayout = rootLayout; +} + bool ExpressionLayoutCursor::privateShowHideEmptyLayoutIfNeeded(bool show) { /* Find Empty layouts adjacent to the cursor: Check the pointed layout and its * neighbour in an Horizontal layout */ diff --git a/poincare/src/layout/dynamic_layout_hierarchy.cpp b/poincare/src/layout/dynamic_layout_hierarchy.cpp index 60b0de32b..c5d11739b 100644 --- a/poincare/src/layout/dynamic_layout_hierarchy.cpp +++ b/poincare/src/layout/dynamic_layout_hierarchy.cpp @@ -33,14 +33,7 @@ DynamicLayoutHierarchy::DynamicLayoutHierarchy(const ExpressionLayout * const * } DynamicLayoutHierarchy::~DynamicLayoutHierarchy() { - if (m_children != nullptr) { - for (int i = 0; i < m_numberOfChildren; i++) { - if (m_children[i] != nullptr) { - delete m_children[i]; - } - } - } - delete[] m_children; + removeAndDeleteChildren(); } void DynamicLayoutHierarchy::mergeChildrenAtIndex(DynamicLayoutHierarchy * eL, int index, bool removeEmptyChildren) { @@ -73,7 +66,9 @@ void DynamicLayoutHierarchy::addChildrenAtIndex(const ExpressionLayout * const * for (int i=indexForInsertion; isetPointedExpressionLayout(editableChild(indexOfNewPointedLayout)); } +void DynamicLayoutHierarchy::removeAndDeleteChildren() { + if (m_children != nullptr) { + for (int i = 0; i < m_numberOfChildren; i++) { + if (m_children[i] != nullptr) { + delete m_children[i]; + } + } + } + delete[] m_children; + m_children = nullptr; + m_numberOfChildren = 0; +} + } diff --git a/poincare/src/layout/expression_layout.cpp b/poincare/src/layout/expression_layout.cpp index 33e26b81d..4926117cc 100644 --- a/poincare/src/layout/expression_layout.cpp +++ b/poincare/src/layout/expression_layout.cpp @@ -110,6 +110,13 @@ bool ExpressionLayout::hasAncestor(const ExpressionLayout * e, bool includeSelf) void ExpressionLayout::collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cursor) { } +ExpressionLayout * ExpressionLayout::editableRoot() { + if (m_parent == nullptr) { + return this; + } + return m_parent->editableRoot(); +} + void ExpressionLayout::addSibling(ExpressionLayoutCursor * cursor, ExpressionLayout * sibling) { privateAddSibling(cursor, sibling, false); }