diff --git a/apps/graph/graph/banner_view.cpp b/apps/graph/graph/banner_view.cpp index c57f3f79d..77ffac29b 100644 --- a/apps/graph/graph/banner_view.cpp +++ b/apps/graph/graph/banner_view.cpp @@ -1,4 +1,5 @@ #include "banner_view.h" +#include "../../i18n.h" namespace Graph { @@ -6,28 +7,31 @@ BannerView::BannerView() : m_abscissaView(KDText::FontSize::Small, 0.5f, 0.5f, KDColorBlack, Palette::GreyMiddle), m_functionView(KDText::FontSize::Small, 0.5f, 0.5f, KDColorBlack, Palette::GreyMiddle), m_derivativeView(KDText::FontSize::Small, 0.5f, 0.5f, KDColorBlack, Palette::GreyMiddle), - m_displayDerivative(false) + m_tangentEquationView(KDText::FontSize::Small, I18n::Message::RegressionFormula, 0.0f, 0.5f, KDColorBlack, Palette::GreyMiddle), + m_aView(KDText::FontSize::Small, 0.5f, 0.5f, KDColorBlack, Palette::GreyMiddle), + m_bView(KDText::FontSize::Small, 0.5f, 0.5f, KDColorBlack, Palette::GreyMiddle), + m_numberOfSubviews(2) { } -void BannerView::setDisplayDerivative(bool displayDerivative) { - m_displayDerivative = displayDerivative; -} - -bool BannerView::displayDerivative() { - return m_displayDerivative; +void BannerView::setNumberOfSubviews(int numberOfSubviews) { + m_numberOfSubviews = numberOfSubviews; } int BannerView::numberOfSubviews() const { - if (m_displayDerivative) { - return 3; - } - return 2; + return m_numberOfSubviews; } TextView * BannerView::textViewAtIndex(int i) const { - const TextView * textViews[3] = {&m_abscissaView, &m_functionView, &m_derivativeView}; + const TextView * textViews[6] = {&m_abscissaView, &m_functionView, &m_derivativeView, &m_tangentEquationView, &m_aView, &m_bView}; return (TextView *)textViews[i]; } +MessageTextView * BannerView::messageTextViewAtIndex(int i) const { + if (i == 3) { + return (MessageTextView *)&m_tangentEquationView; + } + return nullptr; +} + } diff --git a/apps/graph/graph/banner_view.h b/apps/graph/graph/banner_view.h index c2b3bf191..165be7531 100644 --- a/apps/graph/graph/banner_view.h +++ b/apps/graph/graph/banner_view.h @@ -8,15 +8,18 @@ namespace Graph { class BannerView : public Shared::BannerView { public: BannerView(); - void setDisplayDerivative(bool displayDerivative); - bool displayDerivative(); + void setNumberOfSubviews(int numberOfSubviews); private: int numberOfSubviews() const override; TextView * textViewAtIndex(int i) const override; + MessageTextView * messageTextViewAtIndex(int i) const override; BufferTextView m_abscissaView; BufferTextView m_functionView; BufferTextView m_derivativeView; - bool m_displayDerivative; + MessageTextView m_tangentEquationView; + BufferTextView m_aView; + BufferTextView m_bView; + int m_numberOfSubviews; }; } diff --git a/apps/graph/graph/curve_parameter_controller.cpp b/apps/graph/graph/curve_parameter_controller.cpp index 2d26e3913..0b457c67e 100644 --- a/apps/graph/graph/curve_parameter_controller.cpp +++ b/apps/graph/graph/curve_parameter_controller.cpp @@ -10,7 +10,7 @@ namespace Graph { CurveParameterController::CurveParameterController(InteractiveCurveViewRange * graphRange, BannerView * bannerView, CurveViewCursor * cursor, GraphController * graphController) : FunctionCurveParameterController(graphRange, cursor), m_goToParameterController(this, graphRange, cursor, I18n::Message::X), - m_bannerView(bannerView), + m_graphController(graphController), m_calculationCell(I18n::Message::Compute), m_derivativeCell(I18n::Message::DerivateNumber), m_calculationParameterController(this, graphController) @@ -24,7 +24,7 @@ const char * CurveParameterController::title() { void CurveParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (cell == &m_derivativeCell) { SwitchView * switchView = (SwitchView *)m_derivativeCell.accessoryView(); - switchView->setState(m_bannerView->displayDerivative()); + switchView->setState(m_graphController->displayDerivativeInBanner()); } } @@ -46,7 +46,7 @@ bool CurveParameterController::handleEvent(Ion::Events::Event event) { return handleGotoSelection(); case 2: { - m_bannerView->setDisplayDerivative(!m_bannerView->displayDerivative()); + m_graphController->setDisplayDerivativeInBanner(!m_graphController->displayDerivativeInBanner()); m_selectableTableView.reloadData(); return true; } diff --git a/apps/graph/graph/curve_parameter_controller.h b/apps/graph/graph/curve_parameter_controller.h index 9753a9d50..07ca16851 100644 --- a/apps/graph/graph/curve_parameter_controller.h +++ b/apps/graph/graph/curve_parameter_controller.h @@ -21,7 +21,7 @@ public: private: Shared::FunctionGoToParameterController * goToParameterController() override; Shared::FunctionGoToParameterController m_goToParameterController; - BannerView * m_bannerView; + GraphController * m_graphController; constexpr static int k_totalNumberOfCells = 3; MessageTableCellWithChevron m_calculationCell; MessageTableCellWithSwitch m_derivativeCell; diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 5bfd749e5..c316a081a 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -12,7 +12,8 @@ GraphController::GraphController(Responder * parentResponder, CartesianFunctionS m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView), m_graphRange(curveViewRange), m_curveParameterController(curveViewRange, &m_bannerView, m_cursor, this), - m_functionStore(functionStore) + m_functionStore(functionStore), + m_displayDerivativeInBanner(false) { m_graphRange->setDelegate(this); } @@ -56,6 +57,14 @@ void GraphController::setType(GraphView::Type t) { } } +bool GraphController::displayDerivativeInBanner() const { + return m_displayDerivativeInBanner; +} + +void GraphController::setDisplayDerivativeInBanner(bool displayDerivative) { + m_displayDerivativeInBanner = displayDerivative; +} + GraphView::Type GraphController::type() const { return m_view.type(); } @@ -65,25 +74,46 @@ BannerView * GraphController::bannerView() { } void GraphController::reloadBannerView() { - // TODO: do something else if type() == GraphView::Type::tangent FunctionGraphController::reloadBannerView(); - if (!m_bannerView.displayDerivative()) { - return; + m_bannerView.setNumberOfSubviews(2+m_displayDerivativeInBanner); + if (type() == GraphView::Type::Tangent) { + m_bannerView.setNumberOfSubviews(6); } - char buffer[k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; - const char * legend = "00(x)="; - int legendLength = strlen(legend); - strlcpy(buffer, legend, legendLength+1); if (m_functionStore->numberOfActiveFunctions() == 0) { return; } CartesianFunction * f = m_functionStore->activeFunctionAtIndex(m_indexFunctionSelectedByCursor); - buffer[0] = f->name()[0]; - buffer[1] = '\''; TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); - double y = f->approximateDerivative(m_cursor->x(), myApp->localContext()); - Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); - m_bannerView.setLegendAtIndex(buffer, 2); + char buffer[k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + const char * space = " "; + int spaceLength = strlen(space); + if (m_displayDerivativeInBanner || type() == GraphView::Type::Tangent) { + const char * legend = "00(x)="; + int legendLength = strlen(legend); + int numberOfChar = strlcpy(buffer, legend, legendLength+1); + buffer[0] = f->name()[0]; + buffer[1] = '\''; + double y = f->approximateDerivative(m_cursor->x(), myApp->localContext()); + numberOfChar += Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + strlcpy(buffer+numberOfChar, space, spaceLength+1); + buffer[k_maxLegendLength] = 0; + m_bannerView.setLegendAtIndex(buffer, 2); + } + if (type() == GraphView::Type::Tangent) { + const char * legend = "a="; + int legendLength = strlen(legend); + strlcpy(buffer, legend, legendLength+1); + double y = f->approximateDerivative(m_cursor->x(), myApp->localContext()); + Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + m_bannerView.setLegendAtIndex(buffer, 4); + + legend = "b="; + legendLength = strlen(legend); + strlcpy(buffer, legend, legendLength+1); + y = -y*m_cursor->x()+f->evaluateAtAbscissa(m_cursor->x(), myApp->localContext()); + Complex::convertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); + m_bannerView.setLegendAtIndex(buffer, 5); + } } bool GraphController::moveCursorHorizontally(int direction) { diff --git a/apps/graph/graph/graph_controller.h b/apps/graph/graph/graph_controller.h index df2cc4dd3..3ab7cabe7 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -18,6 +18,8 @@ public: I18n::Message emptyMessage() override; bool handleEvent(Ion::Events::Event event) override; void setType(GraphView::Type type); + bool displayDerivativeInBanner() const; + void setDisplayDerivativeInBanner(bool displayDerivative); private: GraphView::Type type() const; BannerView * bannerView() override; @@ -34,6 +36,7 @@ private: Shared::InteractiveCurveViewRange * m_graphRange; CurveParameterController m_curveParameterController; CartesianFunctionStore * m_functionStore; + bool m_displayDerivativeInBanner; }; } diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index eda6d19b3..04fd053af 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -50,6 +50,8 @@ bool FunctionGraphController::handleEnter() { void FunctionGraphController::reloadBannerView() { char buffer[k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)]; + const char * space = " "; + int spaceLength = strlen(space); const char * legend = "0="; int legendLength = strlen(legend); int numberOfChar = 0; @@ -57,9 +59,8 @@ void FunctionGraphController::reloadBannerView() { numberOfChar += legendLength; buffer[0] = functionStore()->symbol(); numberOfChar += Complex::convertFloatToText(m_cursor->x(), buffer+numberOfChar, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); - legend = " "; - legendLength = strlen(legend); - strlcpy(buffer+numberOfChar, legend, legendLength+1); + strlcpy(buffer+numberOfChar, space, spaceLength+1); + buffer[k_maxLegendLength] = 0; bannerView()->setLegendAtIndex(buffer, 0); numberOfChar = 0; @@ -75,9 +76,8 @@ void FunctionGraphController::reloadBannerView() { Function * f = functionStore()->activeFunctionAtIndex(m_indexFunctionSelectedByCursor); buffer[0] = f->name()[0]; numberOfChar += Complex::convertFloatToText(m_cursor->y(), buffer+legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); - legend = " "; - legendLength = strlen(legend); - strlcpy(buffer+numberOfChar, legend, legendLength+1); + strlcpy(buffer+numberOfChar, space, spaceLength+1); + buffer[k_maxLegendLength] = 0; bannerView()->setLegendAtIndex(buffer, 1); } diff --git a/apps/shared/function_graph_controller.h b/apps/shared/function_graph_controller.h index b9a3b8f0c..e0f2f97f5 100644 --- a/apps/shared/function_graph_controller.h +++ b/apps/shared/function_graph_controller.h @@ -21,7 +21,8 @@ protected: constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth constexpr static float k_cursorBottomMarginRatio = 0.15f; // (cursorHeight/2+bannerHeigh)/graphViewHeight constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth - constexpr static int k_maxNumberOfCharacters = 8; + constexpr static int k_maxLegendLength = 14; + constexpr static int k_maxNumberOfCharacters = 50; void reloadBannerView() override; bool handleEnter() override; int m_indexFunctionSelectedByCursor;