diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 5839a50b0..f51dd5eae 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -11,20 +11,14 @@ Calculation::Calculation() : m_exactOutputText(), m_approximateOutputText(), m_input(nullptr), - m_inputLayout(nullptr), m_exactOutput(nullptr), - m_exactOutputLayout(nullptr), m_approximateOutput(nullptr), - m_approximateOutputLayout(nullptr), + m_height(-1), m_equalSign(EqualSign::Unknown) { } Calculation::~Calculation() { - if (m_inputLayout != nullptr) { - delete m_inputLayout; - m_inputLayout = nullptr; - } if (m_input != nullptr) { delete m_input; m_input = nullptr; @@ -33,18 +27,10 @@ Calculation::~Calculation() { delete m_exactOutput; m_exactOutput = nullptr; } - if (m_exactOutputLayout != nullptr) { - delete m_exactOutputLayout; - m_exactOutputLayout = nullptr; - } if (m_approximateOutput != nullptr) { delete m_approximateOutput; m_approximateOutput = nullptr; } - if (m_approximateOutputLayout != nullptr) { - delete m_approximateOutputLayout; - m_approximateOutputLayout = nullptr; - } } Calculation& Calculation::operator=(const Calculation& other) { @@ -78,6 +64,27 @@ void Calculation::setContent(const char * c, Context * context, Expression * ans m_approximateOutput->writeTextInBuffer(m_approximateOutputText, sizeof(m_approximateOutputText)); } +KDCoordinate Calculation::height(Context * context) { + if (m_height < 0) { + ExpressionLayout * inputLayout = createInputLayout(); + KDCoordinate inputHeight = inputLayout->size().height(); + delete inputLayout; + Poincare::ExpressionLayout * approximateLayout = createApproximateOutputLayout(context); + KDCoordinate approximateOutputHeight = approximateLayout->size().height(); + if (shouldOnlyDisplayApproximateOutput(context)) { + m_height = inputHeight+approximateOutputHeight; + } else { + Poincare::ExpressionLayout * exactLayout = createExactOutputLayout(context); + KDCoordinate exactOutputHeight = exactLayout->size().height(); + KDCoordinate outputHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactOutputHeight-exactLayout->baseline(), approximateOutputHeight-approximateLayout->baseline()); + delete exactLayout; + m_height = inputHeight + outputHeight; + } + delete approximateLayout; + } + return m_height; +} + const char * Calculation::inputText() { return m_inputText; } @@ -97,11 +104,11 @@ Expression * Calculation::input() { return m_input; } -ExpressionLayout * Calculation::inputLayout() { - if (m_inputLayout == nullptr && input() != nullptr) { - m_inputLayout = input()->createLayout(PrintFloat::Mode::Decimal, Expression::ComplexFormat::Cartesian); +ExpressionLayout * Calculation::createInputLayout() { + if (input() != nullptr) { + return input()->createLayout(PrintFloat::Mode::Decimal, Expression::ComplexFormat::Cartesian); } - return m_inputLayout; + return nullptr; } bool Calculation::isEmpty() { @@ -123,26 +130,15 @@ void Calculation::tidy() { delete m_input; } m_input = nullptr; - if (m_inputLayout != nullptr) { - delete m_inputLayout; - } - m_inputLayout = nullptr; if (m_exactOutput != nullptr) { delete m_exactOutput; } m_exactOutput = nullptr; - if (m_exactOutputLayout != nullptr) { - delete m_exactOutputLayout; - } - m_exactOutputLayout = nullptr; if (m_approximateOutput != nullptr) { delete m_approximateOutput; } m_approximateOutput = nullptr; - if (m_approximateOutputLayout != nullptr) { - delete m_approximateOutputLayout; - } - m_approximateOutputLayout = nullptr; + m_height = -1; m_equalSign = EqualSign::Unknown; } @@ -155,11 +151,11 @@ Expression * Calculation::exactOutput(Context * context) { return m_exactOutput; } -ExpressionLayout * Calculation::exactOutputLayout(Context * context) { - if (m_exactOutputLayout == nullptr && exactOutput(context) != nullptr) { - m_exactOutputLayout = exactOutput(context)->createLayout(); +ExpressionLayout * Calculation::createExactOutputLayout(Context * context) { + if (exactOutput(context) != nullptr) { + return exactOutput(context)->createLayout(); } - return m_exactOutputLayout; + return nullptr; } Expression * Calculation::approximateOutput(Context * context) { @@ -177,11 +173,11 @@ Expression * Calculation::approximateOutput(Context * context) { return m_approximateOutput; } -ExpressionLayout * Calculation::approximateOutputLayout(Context * context) { - if (m_approximateOutputLayout == nullptr && approximateOutput(context) != nullptr) { - m_approximateOutputLayout = approximateOutput(context)->createLayout(); +ExpressionLayout * Calculation::createApproximateOutputLayout(Context * context) { + if (approximateOutput(context) != nullptr) { + return approximateOutput(context)->createLayout(); } - return m_approximateOutputLayout; + return nullptr; } bool Calculation::shouldOnlyDisplayApproximateOutput(Context * context) { diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index 8a224cd69..68f692876 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -24,15 +24,16 @@ public: /* c.reset() is the equivalent of c = Calculation() without copy assingment. */ void reset(); void setContent(const char * c, Poincare::Context * context, Poincare::Expression * ansExpression); + KDCoordinate height(Poincare::Context * context); const char * inputText(); const char * exactOutputText(); const char * approximateOutputText(); Poincare::Expression * input(); - Poincare::ExpressionLayout * inputLayout(); + Poincare::ExpressionLayout * createInputLayout(); Poincare::Expression * approximateOutput(Poincare::Context * context); Poincare::Expression * exactOutput(Poincare::Context * context); - Poincare::ExpressionLayout * exactOutputLayout(Poincare::Context * context); - Poincare::ExpressionLayout * approximateOutputLayout(Poincare::Context * context); + Poincare::ExpressionLayout * createExactOutputLayout(Poincare::Context * context); + Poincare::ExpressionLayout * createApproximateOutputLayout(Poincare::Context * context); bool isEmpty(); void tidy(); bool shouldOnlyDisplayApproximateOutput(Poincare::Context * context); @@ -46,11 +47,9 @@ private: char m_exactOutputText[k_printedExpressionSize]; char m_approximateOutputText[k_printedExpressionSize]; Poincare::Expression * m_input; - Poincare::ExpressionLayout * m_inputLayout; Poincare::Expression * m_exactOutput; - Poincare::ExpressionLayout * m_exactOutputLayout; Poincare::Expression * m_approximateOutput; - Poincare::ExpressionLayout * m_approximateOutputLayout; + KDCoordinate m_height; EqualSign m_equalSign; }; diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 90bffc092..a30e82b8c 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -158,17 +158,8 @@ KDCoordinate HistoryController::rowHeight(int j) { return 0; } Calculation * calculation = m_calculationStore->calculationAtIndex(j); - KDCoordinate inputHeight = calculation->inputLayout()->size().height(); App * calculationApp = (App *)app(); - Poincare::ExpressionLayout * approximateLayout = calculation->approximateOutputLayout(calculationApp->localContext()); - KDCoordinate approximateOutputHeight = approximateLayout->size().height(); - if (calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext())) { - return inputHeight + approximateOutputHeight + 3*HistoryViewCell::k_digitVerticalMargin; - } - Poincare::ExpressionLayout * exactLayout = calculation->exactOutputLayout(calculationApp->localContext()); - KDCoordinate exactOutputHeight = exactLayout->size().height(); - KDCoordinate outputHeight = max(exactLayout->baseline(), approximateLayout->baseline()) + max(exactOutputHeight-exactLayout->baseline(), approximateOutputHeight-approximateLayout->baseline()); - return inputHeight + outputHeight + 3*HistoryViewCell::k_digitVerticalMargin; + return calculation->height(calculationApp->localContext()) + 3*HistoryViewCell::k_digitVerticalMargin; } KDCoordinate HistoryController::cumulatedHeightFromIndex(int j) { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 3b901f486..7e38a02f8 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -9,12 +9,30 @@ namespace Calculation { HistoryViewCell::HistoryViewCell(Responder * parentResponder) : Responder(parentResponder), + m_inputLayout(nullptr), + m_exactOutputLayout(nullptr), + m_approximateOutputLayout(nullptr), m_inputView(this), m_scrollableOutputView(this), m_selectedSubviewType(HistoryViewCell::SubviewType::Output) { } +HistoryViewCell::~HistoryViewCell() { + if (m_inputLayout != nullptr) { + delete m_inputLayout; + m_inputLayout = nullptr; + } + if (m_exactOutputLayout != nullptr) { + delete m_exactOutputLayout; + m_exactOutputLayout = nullptr; + } + if (m_approximateOutputLayout != nullptr) { + delete m_approximateOutputLayout; + m_approximateOutputLayout = nullptr; + } +} + OutputExpressionsView * HistoryViewCell::outputView() { return m_scrollableOutputView.outputView(); @@ -83,12 +101,27 @@ void HistoryViewCell::layoutSubviews() { } void HistoryViewCell::setCalculation(Calculation * calculation) { - m_inputView.setExpressionLayout(calculation->inputLayout()); + if (m_inputLayout) { + delete m_inputLayout; + } + m_inputLayout = calculation->createInputLayout(); + m_inputView.setExpressionLayout(m_inputLayout); App * calculationApp = (App *)app(); /* Both output expressions have to be updated at the same time. The * outputView points to deleted layouts and a call to * outputView()->layoutSubviews() is going to fail. */ - Poincare::ExpressionLayout * outputExpressions[2] = {calculation->approximateOutputLayout(calculationApp->localContext()), calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext()) ? nullptr : calculation->exactOutputLayout(calculationApp->localContext())}; + if (m_exactOutputLayout) { + delete m_exactOutputLayout; + m_exactOutputLayout = nullptr; + } + if (!calculation->shouldOnlyDisplayApproximateOutput(calculationApp->localContext())) { + m_exactOutputLayout = calculation->createExactOutputLayout(calculationApp->localContext()); + } + if (m_approximateOutputLayout) { + delete m_approximateOutputLayout; + } + m_approximateOutputLayout = calculation->createApproximateOutputLayout(calculationApp->localContext()); + Poincare::ExpressionLayout * outputExpressions[2] = {m_approximateOutputLayout, m_exactOutputLayout}; m_scrollableOutputView.outputView()->setExpressions(outputExpressions); I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(calculationApp->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; m_scrollableOutputView.outputView()->setEqualMessage(equalMessage); diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index d6ca3c1d5..d99063038 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -15,6 +15,7 @@ public: Output }; HistoryViewCell(Responder * parentResponder); + ~HistoryViewCell(); void reloadCell() override; void reloadScroll(); void setEven(bool even) override; @@ -35,6 +36,9 @@ public: OutputExpressionsView * outputView(); private: constexpr static KDCoordinate k_resultWidth = 80; + Poincare::ExpressionLayout * m_inputLayout; + Poincare::ExpressionLayout * m_exactOutputLayout; + Poincare::ExpressionLayout * m_approximateOutputLayout; ScrollableExpressionView m_inputView; ScrollableOutputExpressionsView m_scrollableOutputView; SubviewType m_selectedSubviewType;