diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 50350aee9..4a291baea 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -213,32 +213,10 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( } } -Calculation::AdditionalOutput Calculation::additionalOuput(Context * context) { - Expression exact = exactOutput(); - Expression approx = approximateOutput(context); - ExpressionNode::Type type = exact.type(); - if (type == ExpressionNode::Type::Rational) { - return AdditionalOutput::BaseRepresentation; - } +Poincare::Expression::AdditionalInformationType Calculation::additionalInformationType(Context * context) { Preferences * preferences = Preferences::sharedPreferences(); - Expression imag = ImaginaryPart::Builder(approx); - float i = ApproximateToScalar(imag, context); - if (i != 0.0f) { - return AdditionalOutput::ComplexPlan; - } - if (type == ExpressionNode::Type::Cosine || type == ExpressionNode::Type::Sine) { - float r = ApproximateToScalar(exact.childAtIndex(0), context); - if (!std::isnan(r)) { - return AdditionalOutput::TrigonometryCircle; - } - } - if (approx.type() == ExpressionNode::Type::Matrix) { - Matrix m = static_cast(approx); - if (m.numberOfRows() == m.numberOfColumns() && m.numberOfRows() <= 3) { - return AdditionalOutput::Matrix; - } - } - return AdditionalOutput::None; + Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText); + return exactOutput().additionalInformationType(context, complexFormat, preferences->angleUnit()); } } diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index 6527d3c3f..0961d7591 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -5,6 +5,7 @@ #include #include #include +#include "../shared/poincare_helpers.h" namespace Calculation { @@ -33,14 +34,6 @@ public: ExactAndApproximateToggle }; - enum class AdditionalOutput : uint8_t { - None, - ComplexPlan, - TrigonometryCircle, - BaseRepresentation, - Matrix - }; - /* It is not really the minimal size, but it clears enough space for most * calculations instead of clearing less space, then fail to serialize, clear * more space, fail to serialize, clear more space, etc., until reaching @@ -83,8 +76,8 @@ public: bool shouldOnlyDisplayExactOutput(); EqualSign exactAndApproximateDisplayedOutputsAreEqual(Poincare::Context * context); - // Additional outputs - AdditionalOutput additionalOuput(Poincare::Context * context); + // Additional Information + Poincare::Expression::AdditionalInformationType additionalInformationType(Poincare::Context * context); private: static constexpr KDCoordinate k_heightComputationFailureHeight = 50; /* Buffers holding text expressions have to be longer than the text written diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 324771026..acbab958f 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -3,6 +3,7 @@ #include using namespace Shared; +using namespace Poincare; namespace Calculation { @@ -64,9 +65,12 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { } else { ScrollableExactApproximateExpressionsView::SubviewPosition outputSubviewPosition = selectedCell->outputView()->selectedSubviewPosition(); if (outputSubviewPosition == ScrollableExactApproximateExpressionsView::SubviewPosition::Burger) { - std::complex c; - if (calculation->additionalOuput(App::app()->localContext(), &c) == Calculation::AdditionalOutput::ComplexPlan) { - m_complexController.complexModel()->setComplex(c); + Expression::AdditionalInformationType additionalInfoType = selectedCell->additionalInformationType(); + /* TODO + * Controller * c = additionalInformationType ? graphController : listController? + * m_controller->setType(additionalInformationType)*/ + if (additionalInfoType == Expression::AdditionalInformationType::Complex) { + m_complexController.complexModel()->setComplex(std::complex(1.2f,2.0f)); Container::activeApp()->displayModalViewController(&m_complexController, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, Metric::PopUpTopMargin, Metric::PopUpRightMargin); } } else { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index f53a58949..d4f8ced2a 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -34,7 +34,7 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType, HistoryViewCell::HistoryViewCell(Responder * parentResponder) : Responder(parentResponder), m_calculationDisplayOutput(Calculation::DisplayOutput::Unknown), - m_calculationAdditionalOutput(Calculation::AdditionalOutput::None), + m_calculationAdditionInformation(Poincare::Expression::AdditionalInformationType::None), m_inputView(this), m_scrollableOutputView(this) { @@ -104,7 +104,7 @@ void HistoryViewCell::cellDidSelectSubview(HistoryViewCellDataSource::SubviewTyp * For example, for the calculation 1.2+2 --> 3.2, selecting the output would * display 1.2+2 --> 16/5 = 3.2. */ m_scrollableOutputView.setDisplayLeftLayout(m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximate || (m_calculationDisplayOutput == Calculation::DisplayOutput::ExactAndApproximateToggle && outputSelected)); - m_scrollableOutputView.setDisplayBurger(outputSelected && m_calculationAdditionalOutput != Calculation::AdditionalOutput::None); + m_scrollableOutputView.setDisplayBurger(outputSelected && m_calculationAdditionInformation != Poincare::Expression::AdditionalInformationType::None); /* The displayed outputs have changed. We need to re-layout the cell * and re-initialize the scroll. */ @@ -157,7 +157,7 @@ void HistoryViewCell::setCalculation(Calculation * calculation) { // Memoization m_calculationCRC32 = newCalculationCRC; m_calculationDisplayOutput = calculation->displayOutput(context); - m_calculationAdditionalOutput = calculation->additionalOuput(context); + m_calculationAdditionInformation = calculation->additionalInformationType(context); m_inputView.setLayout(calculation->createInputLayout()); /* Both output expressions have to be updated at the same time. Otherwise, * when updating one layout, if the second one still points to a deleted diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index 36f4e39b2..9265a9dcd 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -47,13 +47,14 @@ public: void didBecomeFirstResponder() override; bool handleEvent(Ion::Events::Event event) override; Shared::ScrollableExactApproximateExpressionsView * outputView(); + Poincare::Expression::AdditionalInformationType additionalInformationType() const { return m_calculationAdditionInformation; } private: constexpr static KDCoordinate k_resultWidth = 80; void reloadScroll(); void reloadOutputSelection(); uint32_t m_calculationCRC32; Calculation::DisplayOutput m_calculationDisplayOutput; - Calculation::AdditionalOutput m_calculationAdditionalOutput; + Poincare::Expression::AdditionalInformationType m_calculationAdditionInformation; ScrollableExpressionView m_inputView; Shared::ScrollableExactApproximateExpressionsView m_scrollableOutputView; HistoryViewCellDataSource * m_dataSource; diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index 05e649fb7..55aa462ff 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -190,6 +190,16 @@ public: int getPolynomialReducedCoefficients(const char * symbolName, Expression coefficients[], Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; Expression replaceSymbolWithExpression(const SymbolAbstract & symbol, const Expression & expression) { return node()->replaceSymbolWithExpression(symbol, expression); } + enum class AdditionalInformationType { + None = 0, + Integer, + Rational, + Trigonometry, + Unit, + Complex + }; + AdditionalInformationType additionalInformationType(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const; + /* Complex */ static bool EncounteredComplex(); static void SetEncounteredComplex(bool encounterComplex); diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 897e013fd..170114088 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -246,6 +246,31 @@ bool Expression::getLinearCoefficients(char * variables, int maxVariableSize, Ex return !isMultivariablePolynomial; } +Expression::AdditionalInformationType Expression::additionalInformationType(Context * context, Preferences::ComplexFormat complexFormat, Preferences::AngleUnit angleUnit) const { + ExpressionNode::Type t = type(); + if (t == ExpressionNode::Type::Rational) { + if (convert().isInteger()) { + return AdditionalInformationType::Integer; + } + return AdditionalInformationType::Rational; + } + if (t == ExpressionNode::Type::Cosine || t == ExpressionNode::Type::Sine) { + float r = childAtIndex(0).approximateToScalar(context, complexFormat, angleUnit); + if (!std::isnan(r)) { + return AdditionalInformationType::Trigonometry; + } + } + // TODO: return AdditionalInformationType::Unit + if (complexFormat != Preferences::ComplexFormat::Real) { + Expression imag = ImaginaryPart::Builder(*this); + float i = imag.approximateToScalar(context, complexFormat, angleUnit); + if (i != 0.0f) { + return AdditionalInformationType::Complex; + } + } + return AdditionalInformationType::None; +} + // Private void Expression::shallowAddMissingParenthesis() {