Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ graph ] Tangent toggle functionnality (#156) #175

Open
wants to merge 7 commits into
base: upsilon-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion apps/apps_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "apps_container_storage.h"
#include "global_preferences.h"
#include "exam_mode_configuration.h"
#include "shared/function_active_function_toggle.h"
#include <ion.h>
#include <poincare/init.h>
#include <poincare/exception_checkpoint.h>
Expand Down Expand Up @@ -37,7 +38,8 @@ AppsContainer::AppsContainer() :
m_homeSnapshot(),
m_onBoardingSnapshot(),
m_hardwareTestSnapshot(),
m_usbConnectedSnapshot()
m_usbConnectedSnapshot(),
m_activeFunctionTooggle(nullptr)
{
m_emptyBatteryWindow.setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height), false);
// #if __EMSCRIPTEN__
Expand Down Expand Up @@ -459,3 +461,7 @@ void AppsContainer::resetShiftAlphaStatus() {
Ion::Events::setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default);
updateAlphaLock();
}

FunctionActiveFunctionToggle *AppsContainer::getActiveFunctionToggle() {
return &m_activeFunctionTooggle;
}
6 changes: 6 additions & 0 deletions apps/apps_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "shared/global_context.h"
#include "clock_timer.h"
#include "on_boarding/prompt_controller.h"
#include "shared/function_active_function_toggle.h"

#include <ion/events.h>

Expand Down Expand Up @@ -55,6 +56,7 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::Storag
// Ion::StorageDelegate
void storageDidChangeForRecord(const Ion::Storage::Record record) override;
void storageIsFull() override;
Shared::FunctionActiveFunctionToggle * getActiveFunctionToggle();
protected:
Home::App::Snapshot * homeAppSnapshot() { return &m_homeSnapshot; }
private:
Expand Down Expand Up @@ -84,6 +86,10 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::Storag
OnBoarding::App::Snapshot m_onBoardingSnapshot;
HardwareTest::App::Snapshot m_hardwareTestSnapshot;
USB::App::Snapshot m_usbConnectedSnapshot;

// Shared Class that need to be initialized at the beginning

Shared::FunctionActiveFunctionToggle m_activeFunctionTooggle;
};

#endif
19 changes: 8 additions & 11 deletions apps/graph/graph/calculation_parameter_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ CalculationParameterController::CalculationParameterController(Responder * paren
ViewController(parentResponder),
m_preimageCell(I18n::Message::Preimage),
m_selectableTableView(this),
m_record(),
m_recordDelegate(nullptr),
m_preimageParameterController(nullptr, inputEventHandlerDelegate, range, cursor, &m_preimageGraphController),
m_preimageGraphController(nullptr, graphView, bannerView, range, cursor),
m_tangentGraphController(nullptr, graphView, bannerView, range, cursor),
m_integralGraphController(nullptr, inputEventHandlerDelegate, graphView, range, cursor),
m_minimumGraphController(nullptr, graphView, bannerView, range, cursor),
m_maximumGraphController(nullptr, graphView, bannerView, range, cursor),
Expand Down Expand Up @@ -45,18 +44,16 @@ void CalculationParameterController::didBecomeFirstResponder() {
bool CalculationParameterController::handleEvent(Ion::Events::Event event) {
int row = selectedRow();
if (event == Ion::Events::OK || event == Ion::Events::EXE || (event == Ion::Events::Right && row == 0)) {
static ViewController * controllers[] = {&m_preimageParameterController, &m_intersectionGraphController, &m_maximumGraphController, &m_minimumGraphController, &m_rootGraphController, &m_tangentGraphController, &m_integralGraphController};
static ViewController * controllers[] = {&m_preimageParameterController, &m_intersectionGraphController, &m_maximumGraphController, &m_minimumGraphController, &m_rootGraphController, &m_integralGraphController};
int displayIntersection = shouldDisplayIntersection();
int indexController = row == 0 ? 0 : row + !displayIntersection;
ViewController * controller = controllers[indexController];
if (row == 0) {
m_preimageParameterController.setRecord(m_record);
m_preimageParameterController.setRecord(m_recordDelegate->getRecord());
} else if (row == 4 + displayIntersection) {
m_tangentGraphController.setRecord(m_record);
} else if (row == 5 + displayIntersection) {
m_integralGraphController.setRecord(m_record);
m_integralGraphController.setRecord(m_recordDelegate->getRecord());
} else {
static_cast<CalculationGraphController *>(controller)->setRecord(m_record);
static_cast<CalculationGraphController *>(controller)->setRecord(m_recordDelegate->getRecord());
}
StackViewController * stack = static_cast<StackViewController *>(parentResponder());
if (row > 0) {
Expand Down Expand Up @@ -108,13 +105,13 @@ int CalculationParameterController::typeAtLocation(int i, int j) {
void CalculationParameterController::willDisplayCellForIndex(HighlightCell * cell, int index) {
assert(index >= 0 && index <= numberOfRows());
if (cell != &m_preimageCell) {
I18n::Message titles[] = {I18n::Message::Intersection, I18n::Message::Maximum, I18n::Message::Minimum, I18n::Message::Zeros, I18n::Message::Tangent, I18n::Message::Integral};
I18n::Message titles[] = {I18n::Message::Intersection, I18n::Message::Maximum, I18n::Message::Minimum, I18n::Message::Zeros, I18n::Message::Integral};
Yaya-Cout marked this conversation as resolved.
Show resolved Hide resolved
static_cast<MessageTableCell *>(cell)->setMessage(titles[index - 1 + !shouldDisplayIntersection()]);
}
}

void CalculationParameterController::setRecord(Ion::Storage::Record record) {
m_record = record;
void CalculationParameterController::setRecordDelegate(Shared::FunctionActiveFunctionToggle * record) {
m_recordDelegate = record;
}

bool CalculationParameterController::shouldDisplayIntersection() const {
Expand Down
8 changes: 4 additions & 4 deletions apps/graph/graph/calculation_parameter_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "root_graph_controller.h"
#include "graph_view.h"
#include "banner_view.h"
#include "apps/shared/function_active_function_toggle.h"
#include <apps/i18n.h>

namespace Graph {
Expand All @@ -29,17 +30,16 @@ class CalculationParameterController : public ViewController, public ListViewDat
int reusableCellCount(int type) override;
int typeAtLocation(int i, int j) override;
void willDisplayCellForIndex(HighlightCell * cell, int index) override;
void setRecord(Ion::Storage::Record record);
void setRecordDelegate(Shared::FunctionActiveFunctionToggle * record);
private:
bool shouldDisplayIntersection() const;
MessageTableCellWithChevron m_preimageCell;
constexpr static int k_totalNumberOfReusableCells = 6;
constexpr static int k_totalNumberOfReusableCells = 5;
MessageTableCell m_cells[k_totalNumberOfReusableCells];
SelectableTableView m_selectableTableView;
Ion::Storage::Record m_record;
Shared::FunctionActiveFunctionToggle * m_recordDelegate;
PreimageParameterController m_preimageParameterController;
PreimageGraphController m_preimageGraphController;
TangentGraphController m_tangentGraphController;
IntegralGraphController m_integralGraphController;
MinimumGraphController m_minimumGraphController;
MaximumGraphController m_maximumGraphController;
Expand Down
19 changes: 14 additions & 5 deletions apps/graph/graph/curve_parameter_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ CurveParameterController::CurveParameterController(InputEventHandlerDelegate * i
m_graphController(graphController),
m_calculationCell(I18n::Message::Compute),
m_derivativeCell(I18n::Message::DerivateNumber),
m_calculationParameterController(this, inputEventHandlerDelegate, graphView, bannerView, graphRange, cursor)
m_calculationParameterController(this, inputEventHandlerDelegate, graphView, bannerView, graphRange, cursor),
m_tangenteCell(I18n::Message::Tangent),
m_tangentGraphController(nullptr, graphView, bannerView, graphRange, cursor)
{
}

Expand All @@ -41,7 +43,7 @@ bool CurveParameterController::handleEvent(Ion::Events::Event event) {
switch (index) {
case 0:
{
m_calculationParameterController.setRecord(m_record);
m_calculationParameterController.setRecordDelegate(m_recordDelegate);
StackViewController * stack = (StackViewController *)parentResponder();
stack->push(&m_calculationParameterController);
return true;
Expand All @@ -54,6 +56,13 @@ bool CurveParameterController::handleEvent(Ion::Events::Event event) {
m_selectableTableView.reloadData();
return true;
}
case 3:
{
m_tangentGraphController.setRecordDelegate(m_recordDelegate);
StackViewController * stack = (StackViewController *)parentResponder();
stack->push(&m_tangentGraphController);
return true;
}
default:
assert(false);
return false;
Expand All @@ -68,12 +77,12 @@ int CurveParameterController::numberOfRows() const {

HighlightCell * CurveParameterController::reusableCell(int index) {
assert(0 <= index && index < reusableCellCount());
HighlightCell * cells[] = {&m_calculationCell, &m_goToCell, &m_derivativeCell};
HighlightCell * cells[] = {&m_calculationCell, &m_goToCell, &m_derivativeCell, &m_tangenteCell};
return cells[cellIndex(index)];
}

int CurveParameterController::reusableCellCount() const {
return 1 + (shouldDisplayCalculationAndDerivative() ? 2 : 0);
return 1 + (shouldDisplayCalculationAndDerivative() ? 3 : 0);
}

void CurveParameterController::viewWillAppear() {
Expand All @@ -82,7 +91,7 @@ void CurveParameterController::viewWillAppear() {
}

bool CurveParameterController::shouldDisplayCalculationAndDerivative() const {
Shared::ExpiringPointer<ContinuousFunction> f = App::app()->functionStore()->modelForRecord(m_record);
Shared::ExpiringPointer<ContinuousFunction> f = App::app()->functionStore()->modelForRecord(m_recordDelegate->getRecord());
return f->plotType() == ContinuousFunction::PlotType::Cartesian;
}

Expand Down
2 changes: 2 additions & 0 deletions apps/graph/graph/curve_parameter_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class CurveParameterController : public Shared::FunctionCurveParameterController
MessageTableCellWithChevron m_calculationCell;
MessageTableCellWithSwitch m_derivativeCell;
CalculationParameterController m_calculationParameterController;
MessageTableCell m_tangenteCell;
TangentGraphController m_tangentGraphController;
};

}
Expand Down
5 changes: 1 addition & 4 deletions apps/graph/graph/graph_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ GraphView::GraphView(InteractiveCurveViewRange * graphRange,
}

void GraphView::reload() {
if (m_tangent) {
KDRect dirtyZone(KDRect(0, 0, bounds().width(), bounds().height()-m_bannerView->bounds().height()));
markRectAsDirty(dirtyZone);
}
markRectAsDirty(bounds());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you not using the AppsContainer reload function ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you use here the AppsContainer reload function, the app just crash when you enter in the graph mode ...

return FunctionGraphView::reload();
}

Expand Down
47 changes: 37 additions & 10 deletions apps/graph/graph/tangent_graph_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ TangentGraphController::TangentGraphController(Responder * parentResponder, Grap
m_graphView(graphView),
m_bannerView(bannerView),
m_graphRange(curveViewRange),
m_record()
m_recordDelegate(nullptr)
{
}

Expand Down Expand Up @@ -47,7 +47,7 @@ bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, co
if (myApp->hasUndefinedValue(text, floatBody)) {
return false;
}
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_record);
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_recordDelegate->getRecord());
assert(function->plotType() == Shared::ContinuousFunction::PlotType::Cartesian);
double y = function->evaluate2DAtParameter(floatBody, myApp->localContext()).x2();
m_cursor->moveTo(floatBody, floatBody, y);
Expand All @@ -57,25 +57,25 @@ bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, co
return true;
}

void TangentGraphController::setRecord(Ion::Storage::Record record) {
m_graphView->selectRecord(record);
m_record = record;
void TangentGraphController::setRecordDelegate(Shared::FunctionActiveFunctionToggle * record) {
m_graphView->selectRecord(record->getRecord());
m_recordDelegate = record;
}

void TangentGraphController::reloadBannerView() {
if (m_record.isNull()) {
if (m_recordDelegate->getRecord().isNull()) {
return;
}
FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, Shared::FunctionApp::app()->functionStore(), AppsContainer::sharedAppsContainer()->globalContext());
GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record);
FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_recordDelegate->getRecord(), Shared::FunctionApp::app()->functionStore(), AppsContainer::sharedAppsContainer()->globalContext());
GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_recordDelegate->getRecord());
constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters + PrintFloat::charSizeForFloatsWithPrecision(Preferences::LargeNumberOfSignificantDigits);
char buffer[bufferSize];
Poincare::Context * context = textFieldDelegateApp()->localContext();

constexpr int precision = Preferences::MediumNumberOfSignificantDigits;
const char * legend = "a=";
int legendLength = strlcpy(buffer, legend, bufferSize);
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_record);
ExpiringPointer<ContinuousFunction> function = App::app()->functionStore()->modelForRecord(m_recordDelegate->getRecord());
double y = function->approximateDerivative(m_cursor->x(), context);
PoincareHelpers::ConvertFloatToText<double>(y, buffer + legendLength, bufferSize - legendLength, precision);
m_bannerView->aView()->setText(buffer);
Expand All @@ -91,7 +91,7 @@ void TangentGraphController::reloadBannerView() {
}

bool TangentGraphController::moveCursorHorizontally(int direction, int scrollSpeed) {
return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_record);
return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_recordDelegate->getRecord());
}

bool TangentGraphController::handleEnter() {
Expand All @@ -100,4 +100,31 @@ bool TangentGraphController::handleEnter() {
return true;
}

bool TangentGraphController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::Up) {
m_recordDelegate->moveUp();
m_graphView->selectRecord(m_recordDelegate->getRecord());
// TODO maybe do: Very ugly workaround... Needs something better to reload the data banner
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you try with the AppsContainer reload function ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup and it's not working (just tried xd).

moveCursorHorizontally(1);
moveCursorHorizontally(-1);

m_graphView->reload();
reloadBannerView();
viewWillAppear();
return true;
} else if (event == Ion::Events::Down) {
m_recordDelegate->moveDown();
m_graphView->selectRecord(m_recordDelegate->getRecord());

moveCursorHorizontally(1);
moveCursorHorizontally(-1);

m_graphView->reload();
reloadBannerView();
viewWillAppear();
return true;
}
return SimpleInteractiveCurveViewController::handleEvent(event);
}

}
10 changes: 8 additions & 2 deletions apps/graph/graph/tangent_graph_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "graph_controller_helper.h"
#include "../../shared/simple_interactive_curve_view_controller.h"
#include "../../shared/function_banner_delegate.h"
#include "apps/shared/function_active_function_toggle.h"

namespace Graph {

Expand All @@ -17,19 +18,24 @@ class TangentGraphController : public Shared::SimpleInteractiveCurveViewControll
void didBecomeFirstResponder() override;
TELEMETRY_ID("Tangent");
bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override;
void setRecord(Ion::Storage::Record record);
void setRecordDelegate(Shared::FunctionActiveFunctionToggle * record);
private:
float cursorBottomMarginRatio() override { return 0.22f; }
Shared::InteractiveCurveViewRange * interactiveCurveViewRange() override { return m_graphRange; }
Shared::CurveView * curveView() override { return m_graphView; }
BannerView * bannerView() override { return m_bannerView; };
void reloadBannerView() override;
bool moveCursorHorizontally(int direction, int scrollSpeed = 1) override;

public:
bool handleEvent(Ion::Events::Event event) override;

private:
bool handleEnter() override;
GraphView * m_graphView;
BannerView * m_bannerView;
Shared::InteractiveCurveViewRange * m_graphRange;
Ion::Storage::Record m_record;
Shared::FunctionActiveFunctionToggle * m_recordDelegate;
};

}
Expand Down
1 change: 1 addition & 0 deletions apps/shared/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ app_shared_src = $(addprefix apps/shared/,\
function_store.cpp \
function_title_cell.cpp \
function_zoom_and_pan_curve_view_controller.cpp \
function_active_function_toggle.cpp \
go_to_parameter_controller.cpp \
hideable_even_odd_buffer_text_cell.cpp \
hideable_even_odd_cell.cpp \
Expand Down
22 changes: 22 additions & 0 deletions apps/shared/function_active_function_toggle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "function_active_function_toggle.h"

Ion::Storage::Record Shared::FunctionActiveFunctionToggle::getRecord() {
if (m_functionStore == nullptr || m_functionStore->numberOfActiveFunctions() <= 0) {
return Ion::Storage::Record();
}
return m_functionStore->activeRecordAtIndex(m_index);
}

void Shared::FunctionActiveFunctionToggle::moveUp() {
if (m_functionStore == nullptr) {
return;
}
m_index = m_functionStore->numberOfActiveFunctions() <= m_index + 1 ? 0 : m_index + 1;
}

void Shared::FunctionActiveFunctionToggle::moveDown() {
if (m_functionStore == nullptr) {
return;
}
m_index = 0 > m_index - 1 ? m_functionStore->numberOfActiveFunctions() - 1 : m_index - 1;
}
27 changes: 27 additions & 0 deletions apps/shared/function_active_function_toggle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef FUNCTION_ACTIVE_FUNCTION_TOGGLE_H
#define FUNCTION_ACTIVE_FUNCTION_TOGGLE_H


#include "../../ion/include/ion/storage.h"
#include "function_store.h"

namespace Shared {

class FunctionActiveFunctionToggle {
public:
explicit FunctionActiveFunctionToggle(FunctionStore * store) : m_functionStore(store), m_index(0) {}

Ion::Storage::Record getRecord();
void setCurrentIndex(int ni) { m_index = ni; }
void setFunctionStorePtr(FunctionStore * store) { m_functionStore = store; }
void moveUp();
void moveDown();

private:
FunctionStore * m_functionStore;
int m_index;

};
}

#endif //FUNCTION_ACTIVE_FUNCTION_TOGGLE_H
Loading