#include "scrollable_three_expressions_cell.h" #include #include "../app.h" namespace Calculation { void ScrollableThreeExpressionsView::resetMemoization() { setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout()); } void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool * didForceOutput) { assert(!didForceOutput || *didForceOutput == false); Poincare::Context * context = App::app()->localContext(); // Clean the layouts to make room in the pool resetMemoization(); // Create the input layout Poincare::Layout inputLayout = calculation->createInputLayout(); // Create the exact output layout Poincare::Layout exactOutputLayout = Poincare::Layout(); if (Calculation::DisplaysExact(calculation->displayOutput(context))) { bool couldNotCreateExactLayout = false; exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout); if (couldNotCreateExactLayout) { if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ExactOnly) { Poincare::ExceptionCheckpoint::Raise(); } else { calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly); if (didForceOutput) { *didForceOutput = true; } } } } Calculation::DisplayOutput displayOutput = calculation->displayOutput(context); // Create the approximate output layout Poincare::Layout approximateOutputLayout = Poincare::Layout(); if (displayOutput == Calculation::DisplayOutput::ExactOnly) { approximateOutputLayout = exactOutputLayout; } else { bool couldNotCreateApproximateLayout = false; approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout); if (couldNotCreateApproximateLayout) { if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) { Poincare::ExceptionCheckpoint::Raise(); } else { /* Set the display output to ApproximateOnly, make room in the pool by * erasing the exact layout, and retry to create the approximate layout */ calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly); if (didForceOutput) { *didForceOutput = true; } exactOutputLayout = Poincare::Layout(); couldNotCreateApproximateLayout = false; approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout); if (couldNotCreateApproximateLayout) { Poincare::ExceptionCheckpoint::Raise(); } } } } setLayouts(inputLayout, exactOutputLayout, approximateOutputLayout); I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(context) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; setEqualMessage(equalMessage); /* The displayed input and outputs have changed. We need to re-layout the cell * and re-initialize the scroll. */ layoutSubviews(); } KDCoordinate ScrollableThreeExpressionsCell::Height(Calculation * calculation) { ScrollableThreeExpressionsCell cell; bool didForceOutput = false; cell.setCalculation(calculation, &didForceOutput); if (didForceOutput) { /* We could not compute the height of the calculation as it is (the display * output was forced to another value during the height computation). * Warning: the display output of calculation was actually changed, so it * will cause problems if we already did some computations with another * display value. */ return -1; } KDRect leftFrame = KDRectZero; KDRect centerFrame = KDRectZero; KDRect approximateSignFrame = KDRectZero; KDRect rightFrame = KDRectZero; cell.subviewFrames(&leftFrame, ¢erFrame, &approximateSignFrame, &rightFrame); KDRect unionedFrame = leftFrame.unionedWith(centerFrame).unionedWith(rightFrame); return unionedFrame.height() + 2 * ScrollableThreeExpressionsView::k_margin; } void ScrollableThreeExpressionsCell::didBecomeFirstResponder() { reinitSelection(); Container::activeApp()->setFirstResponder(&m_view); } void ScrollableThreeExpressionsCell::reinitSelection() { m_view.setSelectedSubviewPosition(ScrollableThreeExpressionsView::SubviewPosition::Left); m_view.reloadScroll(); } void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool * didForceOutput) { m_view.setCalculation(calculation, didForceOutput); layoutSubviews(); } void ScrollableThreeExpressionsCell::setDisplayCenter(bool display) { m_view.setDisplayCenter(display); layoutSubviews(); } }