From 4a5681576cefafb611c81f66f7a5c14903ce04bd Mon Sep 17 00:00:00 2001 From: Joachim LF Date: Thu, 9 Jul 2020 19:17:36 +0200 Subject: [PATCH 01/28] Visual keyboard only change state on keydown --- ion/src/simulator/shared/keyboard_sdl.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ion/src/simulator/shared/keyboard_sdl.cpp b/ion/src/simulator/shared/keyboard_sdl.cpp index a1b173719..3b468914c 100644 --- a/ion/src/simulator/shared/keyboard_sdl.cpp +++ b/ion/src/simulator/shared/keyboard_sdl.cpp @@ -50,6 +50,8 @@ constexpr static KeySDLKeyPair sKeyPairs[] = { constexpr int sNumberOfKeyPairs = sizeof(sKeyPairs)/sizeof(KeySDLKeyPair); +static bool previousState = false; + State scan() { // We need to tell SDL to get new state from the host OS SDL_PumpEvents(); @@ -69,9 +71,13 @@ State scan() { // Register a key for the mouse, if any SDL_Point p; Uint32 mouseState = SDL_GetMouseState(&p.x, &p.y); - if (mouseState & SDL_BUTTON(SDL_BUTTON_LEFT)) { + if (!(previousState) && mouseState & SDL_BUTTON(SDL_BUTTON_LEFT)){ Key k = Simulator::Layout::keyAt(&p); state.setKey(k); + previousState = true; + } + if (!(mouseState & SDL_BUTTON(SDL_BUTTON_LEFT))) { + previousState = false; } #endif From c92b3d49e9a01bd9a23aaa344e04073904914679 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 15 Jul 2020 13:11:27 +0200 Subject: [PATCH 02/28] [apps/calculation] HistoryController: reload the subview selection when deleting row This fixes the following bug: input 1, OK, 1.2 OK, delete the row whose input is '1' with the selection on the output view. The output of 1.2 does not toggle and it should. --- apps/calculation/history_controller.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index c8c153b6a..070ecf1a1 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -129,7 +129,9 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { return true; } m_selectableTableView.selectCellAtLocation(0, focusRow > 0 ? focusRow - 1 : 0); - setSelectedSubviewType(subviewType, true, 0, selectedRow()); + /* The parameters 'sameCell' and 'previousSelectedY' are chosen to enforce + * toggling of the output when necessary. */ + setSelectedSubviewType(subviewType, false, 0, (subviewType == SubviewType::Input) ? selectedRow() : -1); return true; } if (event == Ion::Events::Clear) { From 9e94304db044da879975aa7e9306925881886026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 15 Jul 2020 13:56:34 +0200 Subject: [PATCH 03/28] [poincre/test] Rename assert_simplify -> assert_reduce And assert_expression_simplify -> assert_expression_reduce --- poincare/test/context.cpp | 44 ++++++++++++------------- poincare/test/expression_properties.cpp | 16 ++++----- poincare/test/helper.cpp | 6 ++-- poincare/test/helper.h | 4 +-- poincare/test/simplification.cpp | 30 ++++++++--------- 5 files changed, 50 insertions(+), 50 deletions(-) diff --git a/poincare/test/context.cpp b/poincare/test/context.cpp index b8b8d64dd..b11f65a0f 100644 --- a/poincare/test/context.cpp +++ b/poincare/test/context.cpp @@ -70,8 +70,8 @@ QUIZ_CASE(poincare_context_user_variable_simple) { } QUIZ_CASE(poincare_context_user_variable_2_circular_variables) { - assert_simplify("a→b"); - assert_simplify("b→a"); + assert_reduce("a→b"); + assert_reduce("b→a"); assert_expression_approximates_to("a", Undefined::Name()); assert_expression_approximates_to("b", Undefined::Name()); @@ -81,9 +81,9 @@ QUIZ_CASE(poincare_context_user_variable_2_circular_variables) { } QUIZ_CASE(poincare_context_user_variable_3_circular_variables) { - assert_simplify("a→b"); - assert_simplify("b→c"); - assert_simplify("c→a"); + assert_reduce("a→b"); + assert_reduce("b→c"); + assert_reduce("c→a"); assert_expression_approximates_to("a", Undefined::Name()); assert_expression_approximates_to("b", Undefined::Name()); assert_expression_approximates_to("c", Undefined::Name()); @@ -96,7 +96,7 @@ QUIZ_CASE(poincare_context_user_variable_3_circular_variables) { QUIZ_CASE(poincare_context_user_variable_1_circular_function) { // h: x → h(x) - assert_simplify("h(x)→h(x)"); + assert_reduce("h(x)→h(x)"); assert_expression_approximates_to("h(1)", Undefined::Name()); // Clean the storage for other tests @@ -104,9 +104,9 @@ QUIZ_CASE(poincare_context_user_variable_1_circular_function) { } QUIZ_CASE(poincare_context_user_variable_2_circular_functions) { - assert_simplify("1→f(x)"); - assert_simplify("f(x)→g(x)"); - assert_simplify("g(x)→f(x)"); + assert_reduce("1→f(x)"); + assert_reduce("f(x)→g(x)"); + assert_reduce("g(x)→f(x)"); assert_expression_approximates_to("f(1)", Undefined::Name()); assert_expression_approximates_to("g(1)", Undefined::Name()); @@ -116,10 +116,10 @@ QUIZ_CASE(poincare_context_user_variable_2_circular_functions) { } QUIZ_CASE(poincare_context_user_variable_3_circular_functions) { - assert_simplify("1→f(x)"); - assert_simplify("f(x)→g(x)"); - assert_simplify("g(x)→h(x)"); - assert_simplify("h(x)→f(x)"); + assert_reduce("1→f(x)"); + assert_reduce("f(x)→g(x)"); + assert_reduce("g(x)→h(x)"); + assert_reduce("h(x)→f(x)"); assert_expression_approximates_to("f(1)", Undefined::Name()); assert_expression_approximates_to("g(1)", Undefined::Name()); assert_expression_approximates_to("h(1)", Undefined::Name()); @@ -131,9 +131,9 @@ QUIZ_CASE(poincare_context_user_variable_3_circular_functions) { } QUIZ_CASE(poincare_context_user_variable_circular_variables_and_functions) { - assert_simplify("a→b"); - assert_simplify("b→a"); - assert_simplify("a→f(x)"); + assert_reduce("a→b"); + assert_reduce("b→a"); + assert_reduce("a→f(x)"); assert_expression_approximates_to("f(1)", Undefined::Name()); assert_expression_approximates_to("a", Undefined::Name()); assert_expression_approximates_to("b", Undefined::Name()); @@ -146,21 +146,21 @@ QUIZ_CASE(poincare_context_user_variable_circular_variables_and_functions) { QUIZ_CASE(poincare_context_user_variable_composed_functions) { // f: x→x^2 - assert_simplify("x^2→f(x)"); + assert_reduce("x^2→f(x)"); // g: x→f(x-2) - assert_simplify("f(x-2)→g(x)"); + assert_reduce("f(x-2)→g(x)"); assert_expression_approximates_to("f(2)", "4"); assert_expression_approximates_to("g(3)", "1"); assert_expression_approximates_to("g(5)", "9"); // g: x→f(x-2)+f(x+1) - assert_simplify("f(x-2)+f(x+1)→g(x)"); + assert_reduce("f(x-2)+f(x+1)→g(x)"); // Add a sum to bypass simplification assert_expression_approximates_to("g(3)+sum(1, n, 2, 4)", "20"); assert_expression_approximates_to("g(5)", "45"); // g: x→x+1 - assert_simplify("x+1→g(x)"); + assert_reduce("x+1→g(x)"); assert_expression_approximates_to("f(g(4))", "25"); // Add a sum to bypass simplification assert_expression_approximates_to("f(g(4))+sum(1, n, 2, 4)", "28"); @@ -172,7 +172,7 @@ QUIZ_CASE(poincare_context_user_variable_composed_functions) { QUIZ_CASE(poincare_context_user_variable_functions_approximation_with_value_for_symbol) { // f : x→ x^2 - assert_simplify("x^2→f(x)"); + assert_reduce("x^2→f(x)"); // Approximate f(?-2) with ? = 5 constexpr int bufferSize = CodePoint::MaxCodePointCharLength + 1; @@ -187,7 +187,7 @@ QUIZ_CASE(poincare_context_user_variable_functions_approximation_with_value_for_ Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); // f : x → √(-1) - assert_simplify("√(-1)×√(-1)→f(x)"); + assert_reduce("√(-1)×√(-1)→f(x)"); // Approximate f(?) with ? = 5 // Cartesian assert_parsed_expression_approximates_with_value_for_symbol(Function::Builder("f", 1, Symbol::Builder(UCodePointUnknown)), x, 1.0, -1.0); diff --git a/poincare/test/expression_properties.cpp b/poincare/test/expression_properties.cpp index c55748011..145e533af 100644 --- a/poincare/test/expression_properties.cpp +++ b/poincare/test/expression_properties.cpp @@ -48,7 +48,7 @@ QUIZ_CASE(poincare_properties_is_approximate) { assert_expression_has_property("3.4", &context, Expression::IsApproximate); assert_expression_has_property("2.3+1", &context, Expression::IsApproximate); assert_expression_has_not_property("a", &context, Expression::IsApproximate); - assert_simplify("42.3→a"); + assert_reduce("42.3→a"); assert_expression_has_property("a", &context, Expression::IsApproximate); Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); } @@ -93,7 +93,7 @@ QUIZ_CASE(poincare_properties_is_infinity) { assert_expression_has_property("3.4+inf", &context, Expression::IsInfinity); assert_expression_has_not_property("2.3+1", &context, Expression::IsInfinity); assert_expression_has_not_property("a", &context, Expression::IsInfinity); - assert_simplify("42.3+inf→a"); + assert_reduce("42.3+inf→a"); assert_expression_has_property("a", &context, Expression::IsInfinity); Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); } @@ -155,7 +155,7 @@ QUIZ_CASE(poincare_properties_sign) { assert_reduced_expression_sign("sign(π)", Positive); assert_reduced_expression_sign("sign(-π)", Negative); assert_reduced_expression_sign("a", Unknown); - assert_simplify("42→a"); + assert_reduce("42→a"); assert_reduced_expression_sign("a", Positive); Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); } @@ -232,7 +232,7 @@ QUIZ_CASE(poincare_properties_polynomial_degree) { assert_reduced_expression_polynomial_degree("π×x", 1); assert_reduced_expression_polynomial_degree("√(-1)×x", -1, "x", Real); // f: x→x^2+πx+1 - assert_simplify("1+π×x+x^2→f(x)"); + assert_reduce("1+π×x+x^2→f(x)"); assert_reduced_expression_polynomial_degree("f(x)", 2); Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } @@ -271,7 +271,7 @@ QUIZ_CASE(poincare_properties_characteristic_range) { // cos(cos(x)), degree assert_reduced_expression_has_characteristic_range(Cosine::Builder((Expression)Cosine::Builder(Symbol::Builder(UCodePointUnknown))), 360.0f); // f(x) with f : x --> cos(x), degree - assert_simplify("cos(x)→f(x)"); + assert_reduce("cos(x)→f(x)"); assert_reduced_expression_has_characteristic_range(Function::Builder("f",1,Symbol::Builder(UCodePointUnknown)), 360.0f); Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } @@ -309,7 +309,7 @@ QUIZ_CASE(poincare_properties_get_variables) { assert_expression_has_variables("a+b+c+d+e+f+g+h+i+j+k+l+m+n+o+p+q+r+s+t+aa+bb+cc+dd+ee+ff+gg+hh+ii+jj+kk+ll+mm+nn+oo", variableBuffer6, -1); assert_expression_has_variables("a+b+c+d+e+f+g", variableBuffer6, -1); // f: x→1+πx+x^2+toto - assert_simplify("1+π×x+x^2+toto→f(x)"); + assert_reduce("1+π×x+x^2+toto→f(x)"); const char * variableBuffer7[] = {"tata","toto", ""}; assert_expression_has_variables("f(tata)", variableBuffer7, 2); Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -347,7 +347,7 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) { assert_reduced_expression_has_polynomial_coefficient("x^2-π×x+1", "x", coefficient3); // f: x→x^2+Px+1 - assert_simplify("1+π×x+x^2→f(x)"); + assert_reduce("1+π×x+x^2→f(x)"); const char * coefficient4[] = {"1", "π", "1", 0}; //x^2+π×x+1 assert_reduced_expression_has_polynomial_coefficient("f(x)", "x", coefficient4); const char * coefficient5[] = {"0", "𝐢", 0}; //√(-1)x @@ -356,7 +356,7 @@ QUIZ_CASE(poincare_properties_get_polynomial_coefficients) { assert_reduced_expression_has_polynomial_coefficient("√(-1)x", "x", coefficient6, Real); // 3 -> x - assert_simplify("3→x"); + assert_reduce("3→x"); const char * coefficient7[] = {"4", 0}; assert_reduced_expression_has_polynomial_coefficient("x+1", "x", coefficient7 ); const char * coefficient8[] = {"2", "1", 0}; diff --git a/poincare/test/helper.cpp b/poincare/test/helper.cpp index 417fba00c..399cb589f 100644 --- a/poincare/test/helper.cpp +++ b/poincare/test/helper.cpp @@ -76,13 +76,13 @@ Poincare::Expression parse_expression(const char * expression, Context * context return result; } -void assert_simplify(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) { +void assert_reduce(const char * expression, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target) { Shared::GlobalContext globalContext; Expression e = parse_expression(expression, &globalContext, false); - assert_expression_simplify(e, angleUnit, complexFormat, target, expression); + assert_expression_reduce(e, angleUnit, complexFormat, target, expression); } -void assert_expression_simplify(Expression e, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) { +void assert_expression_reduce(Expression e, Preferences::AngleUnit angleUnit, Preferences::ComplexFormat complexFormat, ExpressionNode::ReductionTarget target, const char * printIfFailure) { Shared::GlobalContext globalContext; e = e.reduce(ExpressionNode::ReductionContext(&globalContext, complexFormat, angleUnit, target)); quiz_assert_print_if_failure(!(e.isUninitialized()), printIfFailure); diff --git a/poincare/test/helper.h b/poincare/test/helper.h index 335efb1a3..afb122eb1 100644 --- a/poincare/test/helper.h +++ b/poincare/test/helper.h @@ -39,9 +39,9 @@ Poincare::Expression parse_expression(const char * expression, Poincare::Context // Simplification -void assert_simplify(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User); +void assert_reduce(const char * expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User); -void assert_expression_simplify(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error"); +void assert_expression_reduce(Poincare::Expression expression, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::ReductionTarget target = User, const char * printIfFailure = "Error"); void assert_parsed_expression_simplify_to(const char * expression, const char * simplifiedExpression, Poincare::ExpressionNode::ReductionTarget target = User, Poincare::Preferences::AngleUnit angleUnit = Radian, Poincare::Preferences::ComplexFormat complexFormat = Cartesian, Poincare::ExpressionNode::SymbolicComputation symbolicComputation = ReplaceAllDefinedSymbolsWithDefinition, Poincare::ExpressionNode::UnitConversion unitConversion = DefaultUnitConversion); diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 00a246928..ffd80f3e4 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -898,7 +898,7 @@ QUIZ_CASE(poincare_simplification_matrix) { assert_parsed_expression_simplify_to("transpose(√(4))", "2"); // Expressions with unreduced matrix - assert_simplify("confidence(cos(2)/25,3)→a"); + assert_reduce("confidence(cos(2)/25,3)→a"); // Check that matrices are not permuted in multiplication assert_parsed_expression_simplify_to("cos(3a)*abs(transpose(a))", "cos(3×confidence(cos(2)/25,3))×abs(transpose(confidence(cos(2)/25,3)))"); assert_parsed_expression_simplify_to("abs(transpose(a))*cos(3a)", "abs(transpose(confidence(cos(2)/25,3)))×cos(3×confidence(cos(2)/25,3))"); @@ -1054,13 +1054,13 @@ QUIZ_CASE(poincare_simplification_unit_convert) { assert_parsed_expression_simplify_to("4→_km/_m", Undefined::Name()); assert_parsed_expression_simplify_to("3×_min→_s+1-1", Undefined::Name()); - assert_simplify("_m→a", Radian, Real); - assert_simplify("_m→b", Radian, Real); + assert_reduce("_m→a", Radian, Real); + assert_reduce("_m→b", Radian, Real); assert_parsed_expression_simplify_to("1_km→a×b", Undefined::Name()); - assert_simplify("2→a"); + assert_reduce("2→a"); assert_parsed_expression_simplify_to("3_m→a×_km", Undefined::Name()); - assert_simplify("2→f(x)"); + assert_reduce("2→f(x)"); assert_parsed_expression_simplify_to("3_m→f(2)×_km", Undefined::Name()); // Clean the storage for other tests @@ -1087,13 +1087,13 @@ QUIZ_CASE(poincare_simplification_complex_format) { // User defined variable assert_parsed_expression_simplify_to("a", "a", User, Radian, Real); // a = 2+i - assert_simplify("2+𝐢→a", Radian, Real); + assert_reduce("2+𝐢→a", Radian, Real); assert_parsed_expression_simplify_to("a", "unreal", User, Radian, Real); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f : x → x+1 - assert_simplify("x+1+𝐢→f(x)", Radian, Real); + assert_reduce("x+1+𝐢→f(x)", Radian, Real); assert_parsed_expression_simplify_to("f(3)", "unreal", User, Radian, Real); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -1173,13 +1173,13 @@ QUIZ_CASE(poincare_simplification_complex_format) { // User defined variable assert_parsed_expression_simplify_to("a", "a", User, Radian, Cartesian); // a = 2+i - assert_simplify("2+𝐢→a", Radian, Cartesian); + assert_reduce("2+𝐢→a", Radian, Cartesian); assert_parsed_expression_simplify_to("a", "2+𝐢", User, Radian, Cartesian); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f : x → x+1 - assert_simplify("x+1+𝐢→f(x)", Radian, Cartesian); + assert_reduce("x+1+𝐢→f(x)", Radian, Cartesian); assert_parsed_expression_simplify_to("f(3)", "4+𝐢", User, Radian, Cartesian); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -1223,13 +1223,13 @@ QUIZ_CASE(poincare_simplification_complex_format) { // User defined variable assert_parsed_expression_simplify_to("a", "a", User, Radian, Polar); // a = 2 + 𝐢 - assert_simplify("2+𝐢→a", Radian, Polar); + assert_reduce("2+𝐢→a", Radian, Polar); assert_parsed_expression_simplify_to("a", "√(5)×ℯ^\u0012\u0012-2×atan(2)+π\u0013/2×𝐢\u0013", User, Radian, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("a.exp").destroy(); // User defined function // f: x → x+1 - assert_simplify("x+1+𝐢→f(x)", Radian, Polar); + assert_reduce("x+1+𝐢→f(x)", Radian, Polar); assert_parsed_expression_simplify_to("f(3)", "√(17)×ℯ^\u0012\u0012-2×atan(4)+π\u0013/2×𝐢\u0013", User, Radian, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -1295,10 +1295,10 @@ QUIZ_CASE(poincare_simplification_unit_conversion) { QUIZ_CASE(poincare_simplification_user_function) { // User defined function // f: x → x*1 - assert_simplify("x*3→f(x)", Radian, Polar); + assert_reduce("x*3→f(x)", Radian, Polar); assert_parsed_expression_simplify_to("f(1+1)", "6", User, Radian, Polar); // f: x → 3 - assert_simplify("3→f(x)", Radian, Polar); + assert_reduce("3→f(x)", Radian, Polar); assert_parsed_expression_simplify_to("f(1/0)", Undefined::Name(), User, Radian, Polar); // Clean the storage for other tests Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); @@ -1315,8 +1315,8 @@ QUIZ_CASE(poincare_simplification_user_function_with_convert) { Function::Builder( "f", 1, Symbol::Builder('x'))); - assert_expression_simplify(e); - assert_simplify("e^(f(0))", Radian, Polar); + assert_expression_reduce(e); + assert_reduce("e^(f(0))", Radian, Polar); Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } From 36bc70aaee4f6e3efb1caa3e461c90076fc50ad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 15 Jul 2020 14:23:39 +0200 Subject: [PATCH 04/28] [poincare/power] Better Power::shallowReduce Take care of an undefined index that arrived during the remove unit --- poincare/src/power.cpp | 4 ++-- poincare/test/simplification.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poincare/src/power.cpp b/poincare/src/power.cpp index 299221d86..dab4c6707 100644 --- a/poincare/src/power.cpp +++ b/poincare/src/power.cpp @@ -407,8 +407,8 @@ Expression Power::shallowReduce(ExpressionNode::ReductionContext reductionContex { Expression indexUnit; index = index.removeUnit(&indexUnit); - if (!indexUnit.isUninitialized()) { - // There must be no unit in the exponent + if (!indexUnit.isUninitialized() || index.isUndefined()) { + // There must be no unit nor undefined in the exponent return replaceWithUndefinedInPlace(); } assert(index == childAtIndex(1)); diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index ffd80f3e4..13860225b 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1316,7 +1316,7 @@ QUIZ_CASE(poincare_simplification_user_function_with_convert) { "f", 1, Symbol::Builder('x'))); assert_expression_reduce(e); - assert_reduce("e^(f(0))", Radian, Polar); + assert_parsed_expression_simplify_to("e^(f(0))", "undef"); Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } From 3a046f5bcb996348d0d3e4e1f4ac10beacfc4ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 15 Jul 2020 14:31:58 +0200 Subject: [PATCH 05/28] [poincare/multiplication] Fix Multiplication::removeUnit Scenario: f(x) = 0->_A evaluate 0f(0) --- poincare/src/multiplication.cpp | 11 +++++++++-- poincare/test/simplification.cpp | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 509e2696f..9eacf74ad 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -264,8 +264,15 @@ Expression Multiplication::removeUnit(Expression * unit) { if (!currentUnit.isUninitialized()) { unitMult.addChildAtIndexInPlace(currentUnit, resultChildrenCount, resultChildrenCount); resultChildrenCount++; - assert(childAtIndex(i).isRationalOne()); - removeChildAtIndexInPlace(i--); + if (childAtIndex(i).isRationalOne()) { + removeChildAtIndexInPlace(i--); + } else { + /* If the child was a unit convert, it replaced itself with an undefined + * during the removeUnit. */ + assert(childAtIndex(i).isUndefined()); + *unit = Expression(); + return replaceWithUndefinedInPlace(); + } } } if (resultChildrenCount == 0) { diff --git a/poincare/test/simplification.cpp b/poincare/test/simplification.cpp index 13860225b..64175b73c 100644 --- a/poincare/test/simplification.cpp +++ b/poincare/test/simplification.cpp @@ -1317,6 +1317,17 @@ QUIZ_CASE(poincare_simplification_user_function_with_convert) { Symbol::Builder('x'))); assert_expression_reduce(e); assert_parsed_expression_simplify_to("e^(f(0))", "undef"); + + e = Store::Builder( + UnitConvert::Builder( + Rational::Builder(0), + Unit::Second()), + Function::Builder( + "f", 1, + Symbol::Builder('x'))); + assert_expression_reduce(e); + assert_parsed_expression_simplify_to("0f(0)", "undef"); + Ion::Storage::sharedStorage()->recordNamed("f.func").destroy(); } From c20261940f340d782d823ae8f9ec03f9b6d83cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 15 Jul 2020 15:53:00 +0200 Subject: [PATCH 06/28] [poincare] Handle removeUnit that create Undefined expressions UnitConvert::removeUnit replaces the unit ocnvert with an undefined. --- poincare/src/addition.cpp | 11 +++++++---- poincare/src/expression.cpp | 4 ++-- poincare/src/multiplication.cpp | 21 ++++++++++----------- poincare/src/unit_convert.cpp | 4 ++-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp index 141cf5a5f..0eaf6aa94 100644 --- a/poincare/src/addition.cpp +++ b/poincare/src/addition.cpp @@ -156,13 +156,16 @@ Expression Addition::shallowReduce(ExpressionNode::ReductionContext reductionCon * the result is not homogeneous. */ { Expression unit; - childAtIndex(0).removeUnit(&unit); + if (childAtIndex(0).removeUnit(&unit).isUndefined()) { + return replaceWithUndefinedInPlace(); + } const bool hasUnit = !unit.isUninitialized(); for (int i = 1; i < childrenCount; i++) { Expression otherUnit; - childAtIndex(i).removeUnit(&otherUnit); - if (hasUnit == otherUnit.isUninitialized() || - (hasUnit && !unit.isIdenticalTo(otherUnit))) + Expression childI = childAtIndex(i).removeUnit(&otherUnit); + if (childI.isUndefined() + || hasUnit == otherUnit.isUninitialized() + || (hasUnit && !unit.isIdenticalTo(otherUnit))) { return replaceWithUndefinedInPlace(); } diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 41b9b04bd..756ddd69a 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -366,8 +366,8 @@ Expression Expression::defaultHandleUnitsInChildren() { const int childrenCount = numberOfChildren(); for (int i = 0; i < childrenCount; i++) { Expression unit; - childAtIndex(i).removeUnit(&unit); - if (!unit.isUninitialized()) { + Expression childI = childAtIndex(i).removeUnit(&unit); + if (childI.isUndefined() || !unit.isUninitialized()) { return replaceWithUndefinedInPlace(); } } diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index 9eacf74ad..af665c7c7 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -260,19 +260,18 @@ Expression Multiplication::removeUnit(Expression * unit) { int resultChildrenCount = 0; for (int i = 0; i < numberOfChildren(); i++) { Expression currentUnit; - childAtIndex(i).removeUnit(¤tUnit); + Expression childI = childAtIndex(i).removeUnit(¤tUnit); + if (childI.isUndefined()) { + /* If the child was a unit convert, it replaced itself with an undefined + * during the removeUnit. */ + *unit = Expression(); + return replaceWithUndefinedInPlace(); + } if (!currentUnit.isUninitialized()) { unitMult.addChildAtIndexInPlace(currentUnit, resultChildrenCount, resultChildrenCount); resultChildrenCount++; - if (childAtIndex(i).isRationalOne()) { - removeChildAtIndexInPlace(i--); - } else { - /* If the child was a unit convert, it replaced itself with an undefined - * during the removeUnit. */ - assert(childAtIndex(i).isUndefined()); - *unit = Expression(); - return replaceWithUndefinedInPlace(); - } + assert(childAtIndex(i).isRationalOne()); + removeChildAtIndexInPlace(i--); } } if (resultChildrenCount == 0) { @@ -371,7 +370,7 @@ Expression Multiplication::shallowBeautify(ExpressionNode::ReductionContext redu self = deepReduce(reductionContext); // removeUnit has to be called on reduced expression self = removeUnit(&units); - if (units.isUninitialized()) { + if (self.isUndefined() || units.isUninitialized()) { // TODO: handle error "Invalid unit" result = Undefined::Builder(); goto replace_by_result; diff --git a/poincare/src/unit_convert.cpp b/poincare/src/unit_convert.cpp index 9807c48be..c8c2acf7c 100644 --- a/poincare/src/unit_convert.cpp +++ b/poincare/src/unit_convert.cpp @@ -59,8 +59,8 @@ Expression UnitConvert::shallowBeautify(ExpressionNode::ReductionContext reducti reductionContext.target(), ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithUndefined); Expression unit; - childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit); - if (unit.isUninitialized()) { + Expression childWithoutUnit = childAtIndex(1).clone().deepReduce(reductionContextWithUnits).removeUnit(&unit); + if (childWithoutUnit.isUndefined() || unit.isUninitialized()) { // There is no unit on the right return replaceWithUndefinedInPlace(); } From b4dd4b5e7efa2c445d951c14e2f2374033a20433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Thu, 16 Jul 2020 11:12:09 +0200 Subject: [PATCH 07/28] [apps/code/i18n] Make italian wording fit --- apps/code/base.it.i18n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/code/base.it.i18n b/apps/code/base.it.i18n index be1e56b8c..a3d5abcbb 100644 --- a/apps/code/base.it.i18n +++ b/apps/code/base.it.i18n @@ -1,7 +1,7 @@ AddScript = "Aggiungere script" AllowedCharactersaz09 = "Caratteri consentiti : a-z, 0-9, _" Autocomplete = "Autocompletamento" -AutoImportScript = "Importazione automatica dello script" +AutoImportScript = "Auto importazione nella console" BuiltinsAndKeywords = "Funzioni native e parole chiave" Console = "Console d'esecuzione" DeleteScript = "Eliminare lo script" From 708477dece23ce3ffb5434767d2cccca78493d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Thu, 16 Jul 2020 11:12:35 +0200 Subject: [PATCH 08/28] [apps/i18n] Fix missing upper case --- apps/toolbox.nl.i18n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/toolbox.nl.i18n b/apps/toolbox.nl.i18n index 65ce2c17e..457824f76 100644 --- a/apps/toolbox.nl.i18n +++ b/apps/toolbox.nl.i18n @@ -107,7 +107,7 @@ BasedLogarithm = "Logaritme met grondtal a" Calculation = "Calculatie" ComplexNumber = "Complexe getallen" Combinatorics = "Combinatoriek" -Arithmetic = "rekenkunde" +Arithmetic = "Rekenkunde" Matrices = "Matrix" NewMatrix = "Nieuwe matrix" Identity = "Eenheidsmatrix van formaat n" From c2db00cc883de0a9c0ee84f1e9cf57f7ece3867f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Jul 2020 11:14:52 +0200 Subject: [PATCH 09/28] [apps/calculation] When leaving calculation app, do not invalid calculation height memoization. They're computed from the layouts which don't depend on the complex format (or any other settings parameters which could have changed). --- apps/calculation/calculation.cpp | 7 +------ apps/calculation/calculation.h | 2 -- apps/calculation/calculation_store.cpp | 3 --- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index f44a40c62..cfa79bb4f 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -38,12 +38,6 @@ Calculation * Calculation::next() const { return reinterpret_cast(const_cast(result)); } -void Calculation::tidy() { - /* Reset height memoization (the complex format could have changed when - * re-entering Calculation app which would impact the heights). */ - resetHeightMemoization(); -} - const char * Calculation::approximateOutputText(NumberOfSignificantDigits numberOfSignificantDigits) const { const char * exactOutput = exactOutputText(); const char * approximateOutputTextWithMaxNumberOfDigits = exactOutput + strlen(exactOutput) + 1; @@ -219,6 +213,7 @@ Calculation::EqualSign Calculation::exactAndApproximateDisplayedOutputsAreEqual( Poincare::ExceptionCheckpoint ecp; if (ExceptionRun(ecp)) { Preferences * preferences = Preferences::sharedPreferences(); + // TODO: complex format should not be needed here (as it is not used to create layouts) Preferences::ComplexFormat complexFormat = Expression::UpdatedComplexFormatWithTextInput(preferences->complexFormat(), m_inputText); m_equalSign = Expression::ParsedExpressionsAreEqual(exactOutputText(), approximateOutputText(NumberOfSignificantDigits::UserDefined), context, complexFormat, preferences->angleUnit()) ? EqualSign::Equal : EqualSign::Approximation; return m_equalSign; diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index a09253abc..01c7f5d5e 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -61,8 +61,6 @@ public: bool operator==(const Calculation& c); Calculation * next() const; - void tidy(); - // Texts enum class NumberOfSignificantDigits { Maximal, diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index fbac03577..47f5ebebf 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -163,9 +163,6 @@ void CalculationStore::tidy() { return; } resetMemoizedModelsAfterCalculationIndex(-1); - for (Calculation * c : *this) { - c->tidy(); - } } Expression CalculationStore::ansExpression(Context * context) { From df74c2c55189dfcb89b773200e43a820094d455f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Jul 2020 11:29:52 +0200 Subject: [PATCH 10/28] [apps/calculation] The heights (common and expanded) of calculation cells are computed when the calculation is added to the store and don't change afterwards. Otherwise, if their heights change when scrolling (due to a modification of the display output type - ExactOnly, ApproximateOnly...), it generates crashes. --- .../complex_list_controller.cpp | 8 ++-- .../illustrated_list_controller.cpp | 11 +----- .../illustrated_list_controller.h | 3 +- .../scrollable_three_expressions_cell.cpp | 37 ++++++------------- .../scrollable_three_expressions_cell.h | 4 +- .../trigonometry_list_controller.cpp | 6 +-- apps/calculation/calculation.cpp | 24 ++++++------ apps/calculation/calculation.h | 9 +++-- apps/calculation/calculation_store.cpp | 20 +++++++--- apps/calculation/calculation_store.h | 5 ++- .../edit_expression_controller.cpp | 4 +- apps/calculation/history_controller.cpp | 15 +------- apps/calculation/history_view_cell.cpp | 28 +++----------- apps/calculation/history_view_cell.h | 2 +- 14 files changed, 65 insertions(+), 111 deletions(-) diff --git a/apps/calculation/additional_outputs/complex_list_controller.cpp b/apps/calculation/additional_outputs/complex_list_controller.cpp index 9bfd3e960..2bbf450c2 100644 --- a/apps/calculation/additional_outputs/complex_list_controller.cpp +++ b/apps/calculation/additional_outputs/complex_list_controller.cpp @@ -26,10 +26,10 @@ void ComplexListController::setExpression(Poincare::Expression e) { } Poincare::Context * context = App::app()->localContext(); // Fill Calculation Store - m_calculationStore.push("im(z)", context); - m_calculationStore.push("re(z)", context); - m_calculationStore.push("arg(z)", context); - m_calculationStore.push("abs(z)", context); + m_calculationStore.push("im(z)", context, CalculationHeight); + m_calculationStore.push("re(z)", context, CalculationHeight); + m_calculationStore.push("arg(z)", context, CalculationHeight); + m_calculationStore.push("abs(z)", context, CalculationHeight); // Set Complex illustration // Compute a and b as in Expression::hasDefinedComplexApproximation to ensure the same defined result diff --git a/apps/calculation/additional_outputs/illustrated_list_controller.cpp b/apps/calculation/additional_outputs/illustrated_list_controller.cpp index 1b78bef20..8c74edc87 100644 --- a/apps/calculation/additional_outputs/illustrated_list_controller.cpp +++ b/apps/calculation/additional_outputs/illustrated_list_controller.cpp @@ -80,16 +80,7 @@ KDCoordinate IllustratedListController::rowHeight(int j) { } Shared::ExpiringPointer calculation = m_calculationStore.calculationAtIndex(calculationIndex); constexpr bool expanded = true; - KDCoordinate result = calculation->memoizedHeight(expanded); - if (result < 0) { - result = ScrollableThreeExpressionsCell::Height(calculation.pointer()); - if (result < 0) { - // Raise, because Height modified the calculation and failed. - Poincare::ExceptionCheckpoint::Raise(); - } - calculation->setMemoizedHeight(expanded, result); - } - return result + Metric::CellSeparatorThickness; + return calculation->height(expanded) + Metric::CellSeparatorThickness; } int IllustratedListController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/additional_outputs/illustrated_list_controller.h b/apps/calculation/additional_outputs/illustrated_list_controller.h index 970341821..ea5b484de 100644 --- a/apps/calculation/additional_outputs/illustrated_list_controller.h +++ b/apps/calculation/additional_outputs/illustrated_list_controller.h @@ -10,8 +10,6 @@ namespace Calculation { class IllustratedListController : public ListController, public SelectableTableViewDelegate { -/* TODO There is factorizable code between this and - * Calculation::HistoryController (at least rowHeight). */ public: IllustratedListController(EditExpressionController * editExpressionController); @@ -35,6 +33,7 @@ public: constexpr static KDCoordinate k_illustrationHeight = 120; protected: + static KDCoordinate CalculationHeight(Calculation * c, bool expanded) { return ScrollableThreeExpressionsCell::Height(c); } Poincare::Expression m_savedExpression; CalculationStore m_calculationStore; private: diff --git a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp index 63cf7b17e..563d49e1a 100644 --- a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp +++ b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.cpp @@ -8,8 +8,8 @@ void ScrollableThreeExpressionsView::resetMemoization() { setLayouts(Poincare::Layout(), Poincare::Layout(), Poincare::Layout()); } -void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool * didForceOutput) { - assert(!didForceOutput || *didForceOutput == false); +// TODO: factorize with HistoryViewCell! +void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) { Poincare::Context * context = App::app()->localContext(); // Clean the layouts to make room in the pool @@ -24,13 +24,10 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b bool couldNotCreateExactLayout = false; exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout); if (couldNotCreateExactLayout) { - if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ExactOnly) { - Poincare::ExceptionCheckpoint::Raise(); - } else { + if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) { calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly); - if (didForceOutput) { - *didForceOutput = true; - } + } else { + Poincare::ExceptionCheckpoint::Raise(); } } } @@ -44,21 +41,18 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b bool couldNotCreateApproximateLayout = false; approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout); if (couldNotCreateApproximateLayout) { - if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) { - Poincare::ExceptionCheckpoint::Raise(); - } else { + if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) { /* 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(); } + } else { + Poincare::ExceptionCheckpoint::Raise(); } } @@ -74,16 +68,7 @@ void ScrollableThreeExpressionsView::setCalculation(Calculation * calculation, b 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; - } + cell.setCalculation(calculation, true); KDRect leftFrame = KDRectZero; KDRect centerFrame = KDRectZero; KDRect approximateSignFrame = KDRectZero; @@ -103,8 +88,8 @@ void ScrollableThreeExpressionsCell::reinitSelection() { m_view.reloadScroll(); } -void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool * didForceOutput) { - m_view.setCalculation(calculation, didForceOutput); +void ScrollableThreeExpressionsCell::setCalculation(Calculation * calculation, bool canChangeDisplayOutput) { + m_view.setCalculation(calculation, canChangeDisplayOutput); layoutSubviews(); } diff --git a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h index e89b68da1..792c65e1d 100644 --- a/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h +++ b/apps/calculation/additional_outputs/scrollable_three_expressions_cell.h @@ -19,7 +19,7 @@ public: setBackgroundColor(KDColorWhite); } void resetMemoization(); - void setCalculation(Calculation * calculation, bool * didForceOutput = nullptr); + void setCalculation(Calculation * calculation, bool canChangeDisplayOutput); void subviewFrames(KDRect * leftFrame, KDRect * centerFrame, KDRect * approximateSignFrame, KDRect * rightFrame) { return m_contentCell.subviewFrames(leftFrame, centerFrame, approximateSignFrame, rightFrame); } @@ -60,7 +60,7 @@ public: void setHighlighted(bool highlight) override { m_view.evenOddCell()->setHighlighted(highlight); } void resetMemoization() { m_view.resetMemoization(); } - void setCalculation(Calculation * calculation, bool * didForceOutput = nullptr); + void setCalculation(Calculation * calculation, bool canChangeDisplayOutput = false); void setDisplayCenter(bool display); ScrollableThreeExpressionsView::SubviewPosition selectedSubviewPosition() { return m_view.selectedSubviewPosition(); } void setSelectedSubviewPosition(ScrollableThreeExpressionsView::SubviewPosition subviewPosition) { m_view.setSelectedSubviewPosition(subviewPosition); } diff --git a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp index a7e0ffa64..b8bdcb076 100644 --- a/apps/calculation/additional_outputs/trigonometry_list_controller.cpp +++ b/apps/calculation/additional_outputs/trigonometry_list_controller.cpp @@ -11,9 +11,9 @@ void TrigonometryListController::setExpression(Poincare::Expression e) { // Fill calculation store Poincare::Context * context = App::app()->localContext(); - m_calculationStore.push("sin(θ)", context); - m_calculationStore.push("cos(θ)", context); - m_calculationStore.push("θ", context); + m_calculationStore.push("sin(θ)", context, CalculationHeight); + m_calculationStore.push("cos(θ)", context, CalculationHeight); + m_calculationStore.push("θ", context, CalculationHeight); // Set trigonometry illustration float angle = Shared::PoincareHelpers::ApproximateToScalar(m_calculationStore.calculationAtIndex(0)->approximateOutput(context, Calculation::NumberOfSignificantDigits::Maximal), context); diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index cfa79bb4f..92d615b5f 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -120,12 +120,15 @@ Layout Calculation::createApproximateOutputLayout(Context * context, bool * coul } } -void Calculation::setMemoizedHeight(bool expanded, KDCoordinate height) { - if (expanded) { - m_expandedHeight = height; - } else { - m_height = height; - } +KDCoordinate Calculation::height(bool expanded) { + KDCoordinate h = expanded ? m_expandedHeight : m_height; + assert(h >= 0); + return h; +} + +void Calculation::setHeights(KDCoordinate height, KDCoordinate expandedHeight) { + m_height = height; + m_expandedHeight = expandedHeight; } Calculation::DisplayOutput Calculation::displayOutput(Context * context) { @@ -184,9 +187,9 @@ Calculation::DisplayOutput Calculation::displayOutput(Context * context) { } void Calculation::forceDisplayOutput(DisplayOutput d) { + // Heights haven't been computed yet + assert(m_height == -1 && m_expandedHeight == -1); m_displayOutput = d; - // Reset heights memoization as it might have changed when we modify the display output - resetHeightMemoization(); } bool Calculation::shouldOnlyDisplayExactOutput() { @@ -284,9 +287,4 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co return AdditionalInformationType::None; } -void Calculation::resetHeightMemoization() { - m_height = -1; - m_expandedHeight = -1; -} - } diff --git a/apps/calculation/calculation.h b/apps/calculation/calculation.h index 01c7f5d5e..ed6e9f2b2 100644 --- a/apps/calculation/calculation.h +++ b/apps/calculation/calculation.h @@ -81,9 +81,8 @@ public: Poincare::Layout createExactOutputLayout(bool * couldNotCreateExactLayout); Poincare::Layout createApproximateOutputLayout(Poincare::Context * context, bool * couldNotCreateApproximateLayout); - // Memoization of height - KDCoordinate memoizedHeight(bool expanded) { return expanded ? m_expandedHeight : m_height; } - void setMemoizedHeight(bool expanded, KDCoordinate height); + // Heights + KDCoordinate height(bool expanded); // Displayed output DisplayOutput displayOutput(Poincare::Context * context); @@ -97,7 +96,9 @@ private: static constexpr int k_numberOfExpressions = 4; static constexpr KDCoordinate k_heightComputationFailureHeight = 50; static constexpr const char * k_maximalIntegerWithAdditionalInformation = "10000000000000000"; - void resetHeightMemoization(); + + void setHeights(KDCoordinate height, KDCoordinate expandedHeight); + /* Buffers holding text expressions have to be longer than the text written * by user (of maximum length TextField::maxBufferSize()) because when we * print an expression we add omitted signs (multiplications, parenthesis...) */ diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index 47f5ebebf..00cef4b06 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -50,7 +50,7 @@ ExpiringPointer CalculationStore::calculationAtIndex(int i) { return calculationAtIndex(i); } -ExpiringPointer CalculationStore::push(const char * text, Context * context) { +ExpiringPointer CalculationStore::push(const char * text, Context * context, CalculationHeight height) { /* Compute ans now, before the buffer is slided and before the calculation * might be deleted */ Expression ans = ansExpression(context); @@ -84,7 +84,7 @@ ExpiringPointer CalculationStore::push(const char * text, Context * /* If the input does not fit in the store (event if the current * calculation is the only calculation), just replace the calculation with * undef. */ - return emptyStoreAndPushUndef(context); + return emptyStoreAndPushUndef(context, height); } nextSerializationLocation += strlen(nextSerializationLocation) + 1; } @@ -115,7 +115,7 @@ ExpiringPointer CalculationStore::push(const char * text, Context * * undef if it fits, else replace the whole calcualtion with undef. */ Expression undef = Undefined::Builder(); if (!pushSerializeExpression(undef, nextSerializationLocation, &newCalculationsLocation)) { - return emptyStoreAndPushUndef(context); + return emptyStoreAndPushUndef(context, height); } } nextSerializationLocation += strlen(nextSerializationLocation) + 1; @@ -132,7 +132,15 @@ ExpiringPointer CalculationStore::push(const char * text, Context * // Clean the memoization resetMemoizedModelsAfterCalculationIndex(-1); - return ExpiringPointer(reinterpret_cast(m_buffer)); + ExpiringPointer calculation = ExpiringPointer(reinterpret_cast(m_buffer)); + /* Heights are computed now to make sure that the display output is decided + * accordingly to the remaining size in the Poincare pool. Once it is, it + * can't change anymore: the calculation heights are fixed which ensures that + * scrolling computation is right. */ + calculation->setHeights( + height(calculation.pointer(), false), + height(calculation.pointer(), true)); + return calculation; } void CalculationStore::deleteCalculationAtIndex(int i) { @@ -251,12 +259,12 @@ const char * CalculationStore::lastCalculationPosition(const char * calculations return reinterpret_cast(c); } -Shared::ExpiringPointer CalculationStore::emptyStoreAndPushUndef(Context * context) { +Shared::ExpiringPointer CalculationStore::emptyStoreAndPushUndef(Context * context, CalculationHeight height) { /* We end up here as a result of a failed calculation push. The store * attributes are not necessarily clean, so we need to reset them. */ m_slidedBuffer = false; deleteAll(); - return push(Undefined::Name(), context); + return push(Undefined::Name(), context, height); } void CalculationStore::resetMemoizedModelsAfterCalculationIndex(int index) { diff --git a/apps/calculation/calculation_store.h b/apps/calculation/calculation_store.h index 9c2185f88..872115649 100644 --- a/apps/calculation/calculation_store.h +++ b/apps/calculation/calculation_store.h @@ -28,7 +28,8 @@ class CalculationStore { public: CalculationStore(); Shared::ExpiringPointer calculationAtIndex(int i); - Shared::ExpiringPointer push(const char * text, Poincare::Context * context); + typedef KDCoordinate (*CalculationHeight)(Calculation * c, bool expanded); + Shared::ExpiringPointer push(const char * text, Poincare::Context * context, CalculationHeight height); void deleteCalculationAtIndex(int i); void deleteAll(); int numberOfCalculations() const { return m_numberOfCalculations; } @@ -60,7 +61,7 @@ private: char * slideCalculationsToEndOfBuffer(); // returns the new position of the calculations size_t deleteLastCalculation(const char * calculationsStart = nullptr); const char * lastCalculationPosition(const char * calculationsStart) const; - Shared::ExpiringPointer emptyStoreAndPushUndef(Poincare::Context * context); + Shared::ExpiringPointer emptyStoreAndPushUndef(Poincare::Context * context, CalculationHeight height); char m_buffer[k_bufferSize]; const char * m_bufferEnd; diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index cd7702e93..2ae7929a9 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -122,7 +122,7 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event if (!myApp->isAcceptableText(m_cacheBuffer)) { return true; } - m_calculationStore->push(m_cacheBuffer, myApp->localContext()); + m_calculationStore->push(m_cacheBuffer, myApp->localContext(), HistoryViewCell::Height); m_historyController->reload(); return true; } @@ -145,7 +145,7 @@ bool EditExpressionController::inputViewDidFinishEditing(const char * text, Layo } else { layoutR.serializeParsedExpression(m_cacheBuffer, k_cacheBufferSize, context); } - m_calculationStore->push(m_cacheBuffer, context); + m_calculationStore->push(m_cacheBuffer, context, HistoryViewCell::Height); m_historyController->reload(); m_contentView.expressionField()->setEditing(true, true); telemetryReportEvent("Input", m_cacheBuffer); diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 070ecf1a1..16e68704d 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -206,20 +206,7 @@ KDCoordinate HistoryController::rowHeight(int j) { } Shared::ExpiringPointer calculation = calculationAtIndex(j); bool expanded = j == selectedRow() && selectedSubviewType() == SubviewType::Output; - KDCoordinate result = calculation->memoizedHeight(expanded); - if (result < 0) { - result = HistoryViewCell::Height(calculation.pointer(), expanded); - if (result < 0) { - // Raise, because Height modified the calculation and failed. - Poincare::ExceptionCheckpoint::Raise(); - } - calculation->setMemoizedHeight(expanded, result); - } - /* We might want to put an assertion here to check the memoization: - * assert(result == HistoryViewCell::Height(calculation.pointer(), expanded)); - * However, Height might fail due to pool memory exhaustion, in which case the - * assertion fails even if "result" had the right value. */ - return result; + return calculation->height(expanded); } int HistoryController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 2f982053d..e560ccbf3 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -36,16 +36,7 @@ void HistoryViewCellDataSource::setSelectedSubviewType(SubviewType subviewType, KDCoordinate HistoryViewCell::Height(Calculation * calculation, bool expanded) { HistoryViewCell cell(nullptr); - bool didForceOutput = false; - cell.setCalculation(calculation, expanded, &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; - } + cell.setCalculation(calculation, expanded, true); KDRect ellipsisFrame = KDRectZero; KDRect inputFrame = KDRectZero; KDRect outputFrame = KDRectZero; @@ -246,8 +237,7 @@ void HistoryViewCell::resetMemoization() { m_calculationCRC32 = 0; } -void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput) { - assert(!didForceOutput || *didForceOutput == false); +void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput) { uint32_t newCalculationCRC = Ion::crc32Byte((const uint8_t *)calculation, ((char *)calculation->next()) - ((char *) calculation)); if (newCalculationCRC == m_calculationCRC32 && m_calculationExpanded == expanded) { return; @@ -273,11 +263,8 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, b bool couldNotCreateExactLayout = false; exactOutputLayout = calculation->createExactOutputLayout(&couldNotCreateExactLayout); if (couldNotCreateExactLayout) { - if (calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) { + if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ExactOnly) { calculation->forceDisplayOutput(::Calculation::Calculation::DisplayOutput::ApproximateOnly); - if (didForceOutput) { - *didForceOutput = true; - } } else { /* We should only display the exact result, but we cannot create it * -> raise an exception. */ @@ -294,21 +281,18 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded, b bool couldNotCreateApproximateLayout = false; approximateOutputLayout = calculation->createApproximateOutputLayout(context, &couldNotCreateApproximateLayout); if (couldNotCreateApproximateLayout) { - if (calculation->displayOutput(context) == ::Calculation::Calculation::DisplayOutput::ApproximateOnly) { - Poincare::ExceptionCheckpoint::Raise(); - } else { + if (canChangeDisplayOutput && calculation->displayOutput(context) != ::Calculation::Calculation::DisplayOutput::ApproximateOnly) { /* 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(); } + } else { + Poincare::ExceptionCheckpoint::Raise(); } } } diff --git a/apps/calculation/history_view_cell.h b/apps/calculation/history_view_cell.h index abe2d6ac8..5e296f529 100644 --- a/apps/calculation/history_view_cell.h +++ b/apps/calculation/history_view_cell.h @@ -51,7 +51,7 @@ public: Poincare::Layout layout() const override; KDColor backgroundColor() const override { return m_even ? KDColorWhite : Palette::WallScreen; } void resetMemoization(); - void setCalculation(Calculation * calculation, bool expanded, bool * didForceOutput = nullptr); + void setCalculation(Calculation * calculation, bool expanded, bool canChangeDisplayOutput = false); int numberOfSubviews() const override { return 2 + displayedEllipsis(); } View * subviewAtIndex(int index) override; void layoutSubviews(bool force = false) override; From 1fb8c09714761c50ca9a61bf9a94fc4204dde07f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Jul 2020 11:33:04 +0200 Subject: [PATCH 11/28] [apps/calculation] Remove old TODOs --- .../additional_outputs/illustrated_list_controller.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/calculation/additional_outputs/illustrated_list_controller.cpp b/apps/calculation/additional_outputs/illustrated_list_controller.cpp index 8c74edc87..370729bb2 100644 --- a/apps/calculation/additional_outputs/illustrated_list_controller.cpp +++ b/apps/calculation/additional_outputs/illustrated_list_controller.cpp @@ -89,7 +89,6 @@ int IllustratedListController::typeAtLocation(int i, int j) { void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (index == 0) { - // TODO ? return; } Poincare::Context * context = App::app()->localContext(); @@ -97,7 +96,6 @@ void IllustratedListController::willDisplayCellForIndex(HighlightCell * cell, in Calculation * c = m_calculationStore.calculationAtIndex(index-1).pointer(); myCell->setCalculation(c); myCell->setDisplayCenter(c->displayOutput(context) != Calculation::DisplayOutput::ApproximateOnly); - //myCell->setHighlighted(myCell->isHighlighted()); //TODO?? } void IllustratedListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { From 83ecefda00d3398d90508c3a9c3cd73c3997c13a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Jul 2020 11:52:45 +0200 Subject: [PATCH 12/28] [apps/calculation] Fix tests --- apps/calculation/test/calculation_store.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/calculation/test/calculation_store.cpp b/apps/calculation/test/calculation_store.cpp index 48e1af129..eb2045778 100644 --- a/apps/calculation/test/calculation_store.cpp +++ b/apps/calculation/test/calculation_store.cpp @@ -14,6 +14,7 @@ void assert_store_is(CalculationStore * store, const char * * result) { } } +KDCoordinate dummyHeight(::Calculation::Calculation * c, bool expanded) { return 0; } QUIZ_CASE(calculation_store) { Shared::GlobalContext globalContext; @@ -22,7 +23,7 @@ QUIZ_CASE(calculation_store) { const char * result[] = {"9", "8", "7", "6", "5", "4", "3", "2", "1", "0"}; for (int i = 0; i < 10; i++) { char text[2] = {(char)(i+'0'), 0}; - store.push(text, &globalContext); + store.push(text, &globalContext, dummyHeight); quiz_assert(store.numberOfCalculations() == i+1); } assert_store_is(&store, result); @@ -41,13 +42,13 @@ QUIZ_CASE(calculation_ans) { Shared::GlobalContext globalContext; CalculationStore store; - store.push("1+3/4", &globalContext); - store.push("ans+2/3", &globalContext); + store.push("1+3/4", &globalContext, dummyHeight); + store.push("ans+2/3", &globalContext, dummyHeight); Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store.calculationAtIndex(0); quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximate); quiz_assert(strcmp(lastCalculation->exactOutputText(),"29/12") == 0); - store.push("ans+0.22", &globalContext); + store.push("ans+0.22", &globalContext, dummyHeight); lastCalculation = store.calculationAtIndex(0); quiz_assert(lastCalculation->displayOutput(&globalContext) == ::Calculation::Calculation::DisplayOutput::ExactAndApproximateToggle); quiz_assert(strcmp(lastCalculation->approximateOutputText(::Calculation::Calculation::NumberOfSignificantDigits::Maximal),"2.6366666666667") == 0); @@ -56,7 +57,7 @@ QUIZ_CASE(calculation_ans) { } void assertCalculationIs(const char * input, ::Calculation::Calculation::DisplayOutput display, ::Calculation::Calculation::EqualSign sign, const char * exactOutput, const char * displayedApproximateOutput, const char * storedApproximateOutput, Context * context, CalculationStore * store) { - store->push(input, context); + store->push(input, context, dummyHeight); Shared::ExpiringPointer<::Calculation::Calculation> lastCalculation = store->calculationAtIndex(0); quiz_assert(lastCalculation->displayOutput(context) == display); if (sign != ::Calculation::Calculation::EqualSign::Unknown) { From 22549d4d507ee50e1cc8f24a22142eb938ac9478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Thu, 16 Jul 2020 14:14:21 +0200 Subject: [PATCH 13/28] [apps/calculation] CalculationStore: change name CalculationHeight --> HeightComputer --- apps/calculation/calculation_store.cpp | 14 +++++++------- apps/calculation/calculation_store.h | 6 +++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/calculation/calculation_store.cpp b/apps/calculation/calculation_store.cpp index 00cef4b06..d39684424 100644 --- a/apps/calculation/calculation_store.cpp +++ b/apps/calculation/calculation_store.cpp @@ -50,7 +50,7 @@ ExpiringPointer CalculationStore::calculationAtIndex(int i) { return calculationAtIndex(i); } -ExpiringPointer CalculationStore::push(const char * text, Context * context, CalculationHeight height) { +ExpiringPointer CalculationStore::push(const char * text, Context * context, HeightComputer heightComputer) { /* Compute ans now, before the buffer is slided and before the calculation * might be deleted */ Expression ans = ansExpression(context); @@ -84,7 +84,7 @@ ExpiringPointer CalculationStore::push(const char * text, Context * /* If the input does not fit in the store (event if the current * calculation is the only calculation), just replace the calculation with * undef. */ - return emptyStoreAndPushUndef(context, height); + return emptyStoreAndPushUndef(context, heightComputer); } nextSerializationLocation += strlen(nextSerializationLocation) + 1; } @@ -115,7 +115,7 @@ ExpiringPointer CalculationStore::push(const char * text, Context * * undef if it fits, else replace the whole calcualtion with undef. */ Expression undef = Undefined::Builder(); if (!pushSerializeExpression(undef, nextSerializationLocation, &newCalculationsLocation)) { - return emptyStoreAndPushUndef(context, height); + return emptyStoreAndPushUndef(context, heightComputer); } } nextSerializationLocation += strlen(nextSerializationLocation) + 1; @@ -138,8 +138,8 @@ ExpiringPointer CalculationStore::push(const char * text, Context * * can't change anymore: the calculation heights are fixed which ensures that * scrolling computation is right. */ calculation->setHeights( - height(calculation.pointer(), false), - height(calculation.pointer(), true)); + heightComputer(calculation.pointer(), false), + heightComputer(calculation.pointer(), true)); return calculation; } @@ -259,12 +259,12 @@ const char * CalculationStore::lastCalculationPosition(const char * calculations return reinterpret_cast(c); } -Shared::ExpiringPointer CalculationStore::emptyStoreAndPushUndef(Context * context, CalculationHeight height) { +Shared::ExpiringPointer CalculationStore::emptyStoreAndPushUndef(Context * context, HeightComputer heightComputer) { /* We end up here as a result of a failed calculation push. The store * attributes are not necessarily clean, so we need to reset them. */ m_slidedBuffer = false; deleteAll(); - return push(Undefined::Name(), context, height); + return push(Undefined::Name(), context, heightComputer); } void CalculationStore::resetMemoizedModelsAfterCalculationIndex(int index) { diff --git a/apps/calculation/calculation_store.h b/apps/calculation/calculation_store.h index 872115649..9f69d3edf 100644 --- a/apps/calculation/calculation_store.h +++ b/apps/calculation/calculation_store.h @@ -28,8 +28,8 @@ class CalculationStore { public: CalculationStore(); Shared::ExpiringPointer calculationAtIndex(int i); - typedef KDCoordinate (*CalculationHeight)(Calculation * c, bool expanded); - Shared::ExpiringPointer push(const char * text, Poincare::Context * context, CalculationHeight height); + typedef KDCoordinate (*HeightComputer)(Calculation * c, bool expanded); + Shared::ExpiringPointer push(const char * text, Poincare::Context * context, HeightComputer heightComputer); void deleteCalculationAtIndex(int i); void deleteAll(); int numberOfCalculations() const { return m_numberOfCalculations; } @@ -61,7 +61,7 @@ private: char * slideCalculationsToEndOfBuffer(); // returns the new position of the calculations size_t deleteLastCalculation(const char * calculationsStart = nullptr); const char * lastCalculationPosition(const char * calculationsStart) const; - Shared::ExpiringPointer emptyStoreAndPushUndef(Poincare::Context * context, CalculationHeight height); + Shared::ExpiringPointer emptyStoreAndPushUndef(Poincare::Context * context, HeightComputer heightComputer); char m_buffer[k_bufferSize]; const char * m_bufferEnd; From 3e6e1729a2e2b1431c355d192e1381f6afb505c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 20 Jul 2020 10:12:01 +0200 Subject: [PATCH 14/28] [ion/device] Add screen id for gamma calibration --- ion/src/device/shared/drivers/display.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ion/src/device/shared/drivers/display.cpp b/ion/src/device/shared/drivers/display.cpp index fdf504847..508242dde 100644 --- a/ion/src/device/shared/drivers/display.cpp +++ b/ion/src/device/shared/drivers/display.cpp @@ -434,8 +434,9 @@ void initPanel() { // Calibration const uint8_t * gammaCalibration = nullptr; uint32_t panelId = panelIdentifier(); - if (panelId == 0x4E4101) { - // Don't forget the "static" qualifier, otherwise this array can be deleted before reaching send_long_command + if (panelId == 0x4E4101 || panelId == 0x4E4801) { + /* Don't forget the "static" qualifier, otherwise this array can be deleted + * before reaching send_long_command. */ static const uint8_t calibration[] = {0xA2, 0xA, 0x11, 0xA, 0xC, 0x1A, 0x34, 0x22, 0x4D, 0x28, 0x15, 0x13, 0x29, 0x2D}; gammaCalibration = calibration; } From 2f246ad604751a222b4bf272381d81e6adb934b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Guid=C3=A9e?= Date: Thu, 23 Jul 2020 20:15:24 +0200 Subject: [PATCH 15/28] [android] Change SDK version to 29 --- ion/src/simulator/android/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ion/src/simulator/android/build.gradle b/ion/src/simulator/android/build.gradle index a620bb823..bb48650fd 100644 --- a/ion/src/simulator/android/build.gradle +++ b/ion/src/simulator/android/build.gradle @@ -36,7 +36,7 @@ android { defaultConfig { applicationId "io.github.omega.simulator" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 29 def (major, minor, patch) = System.getenv('OMEGA_VERSION').toLowerCase().tokenize('.').collect{it.toInteger()} versionCode major*1000000 + minor*10000 + patch * 100 versionName System.getenv('OMEGA_VERSION') From 7fc145d455c5686e872d193d8ba55772fe4227ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Guid=C3=A9e?= Date: Thu, 23 Jul 2020 23:22:31 +0200 Subject: [PATCH 16/28] [apps/settings] remove LEDS_CHOICE --- Makefile | 1 - apps/apps_container.cpp | 25 +---------- apps/exam_mode_configuration.h | 4 -- apps/exam_mode_configuration_non_official.cpp | 28 +----------- .../sub_menu/exam_mode_controller.cpp | 23 ---------- apps/settings/sub_menu/exam_mode_controller.h | 3 -- .../sub_menu/preferences_controller.cpp | 44 ------------------- apps/shared.de.i18n | 8 ---- apps/shared.en.i18n | 8 ---- apps/shared.es.i18n | 8 ---- apps/shared.fr.i18n | 8 ---- apps/shared.hu.i18n | 8 ---- apps/shared.it.i18n | 8 ---- apps/shared.nl.i18n | 8 ---- apps/shared.pt.i18n | 8 ---- build/config.mak | 1 - build/defaults.mak | 1 - poincare/include/poincare/preferences.h | 12 ----- poincare/src/preferences.cpp | 1 - 19 files changed, 2 insertions(+), 205 deletions(-) diff --git a/Makefile b/Makefile index 158ae9f57..f83a5922f 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,6 @@ info: @echo "BUILD_DIR = $(BUILD_DIR)" @echo "PLATFORM" = $(PLATFORM) @echo "DEBUG" = $(DEBUG) - @echo "LEDS_CHOICE" = $(LEDS_CHOICE) @echo "EPSILON_GETOPT" = $(EPSILON_GETOPT) @echo "ESCHER_LOG_EVENTS_BINARY" = $(ESCHER_LOG_EVENTS_BINARY) @echo "QUIZ_USE_CONSOLE" = $(QUIZ_USE_CONSOLE) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index dd0b90207..cbdcae2ed 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -374,30 +374,7 @@ void AppsContainer::redrawWindow(bool force) { void AppsContainer::activateExamMode(GlobalPreferences::ExamMode examMode) { assert(examMode != GlobalPreferences::ExamMode::Off && examMode != GlobalPreferences::ExamMode::Unknown); reset(); - Preferences * preferences = Preferences::sharedPreferences(); - switch ((int)preferences->colorOfLED()) { - case 0: - Ion::LED::setColor(KDColorRed); - break; - case 1: - Ion::LED::setColor(KDColorWhite); - break; - case 2: - Ion::LED::setColor(KDColorGreen); - break; - case 3: - Ion::LED::setColor(KDColorBlue); - break; - case 4: - Ion::LED::setColor(KDColorYellow); - break; - case 5: - Ion::LED::setColor(KDColorPurple); - break; - case 6: - Ion::LED::setColor(KDColorOrange); - break; - } + Ion::LED::setColor(KDColorRed); /* The Dutch exam mode LED is supposed to be orange but we can only make * blink "pure" colors: with RGB leds on or off (as the PWM is used for * blinking). The closest "pure" color is Yellow. Moreover, Orange LED is diff --git a/apps/exam_mode_configuration.h b/apps/exam_mode_configuration.h index e269ede0f..7ec6e4201 100644 --- a/apps/exam_mode_configuration.h +++ b/apps/exam_mode_configuration.h @@ -8,11 +8,7 @@ namespace ExamModeConfiguration { // Settings menu -#if LEDS_CHOICE -extern const Shared::SettingsMessageTree s_modelExamChildren[3]; -#else extern const Shared::SettingsMessageTree s_modelExamChildren[2]; -#endif int numberOfAvailableExamMode(); GlobalPreferences::ExamMode examModeAtIndex(int index); I18n::Message examModeActivationMessage(int index); diff --git a/apps/exam_mode_configuration_non_official.cpp b/apps/exam_mode_configuration_non_official.cpp index d22a24913..b535e5037 100644 --- a/apps/exam_mode_configuration_non_official.cpp +++ b/apps/exam_mode_configuration_non_official.cpp @@ -3,19 +3,10 @@ using namespace Poincare; constexpr Shared::SettingsMessageTree s_examModeMode[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeModeStandard), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSym), Shared::SettingsMessageTree(I18n::Message::ExamModeModeNoSymNoText)}; -#if LEDS_CHOICE -constexpr Shared::SettingsMessageTree s_ledColorChildren[] = {Shared::SettingsMessageTree(I18n::Message::ColorRed), Shared::SettingsMessageTree(I18n::Message::ColorWhite), Shared::SettingsMessageTree(I18n::Message::ColorGreen), Shared::SettingsMessageTree(I18n::Message::ColorBlue), Shared::SettingsMessageTree(I18n::Message::ColorYellow), Shared::SettingsMessageTree(I18n::Message::ColorPurple), Shared::SettingsMessageTree(I18n::Message::ColorOrange)}; -constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::LEDColor, s_ledColorChildren), Shared::SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode), Shared::SettingsMessageTree(I18n::Message::ActivateExamMode)}; -#else constexpr Shared::SettingsMessageTree ExamModeConfiguration::s_modelExamChildren[] = {Shared::SettingsMessageTree(I18n::Message::ExamModeMode, s_examModeMode), Shared::SettingsMessageTree(I18n::Message::ActivateExamMode)}; -#endif int ExamModeConfiguration::numberOfAvailableExamMode() { -#if LEDS_CHOICE - return 3; -#else return 2; -#endif } GlobalPreferences::ExamMode ExamModeConfiguration::examModeAtIndex(int index) { @@ -38,24 +29,7 @@ I18n::Message ExamModeConfiguration::examModeActivationWarningMessage(GlobalPref KDColor ExamModeConfiguration::examModeColor(GlobalPreferences::ExamMode mode) { assert(mode == GlobalPreferences::ExamMode::Standard || mode == GlobalPreferences::ExamMode::NoSym || mode == GlobalPreferences::ExamMode::NoSymNoText); - Preferences * preferences = Preferences::sharedPreferences(); - - switch((int) preferences->colorOfLED()) { - case 1: - return KDColorWhite; - case 2: - return KDColorGreen; - case 3: - return KDColorBlue; - case 4: - return KDColorYellow; - case 5: - return KDColorPurple; - case 6: - return KDColorOrange; - default: - return KDColorRed; - } + return KDColorRed; } bool ExamModeConfiguration::appIsForbiddenInExamMode(App::Descriptor::ExaminationLevel appExaminationLevel, GlobalPreferences::ExamMode mode) { diff --git a/apps/settings/sub_menu/exam_mode_controller.cpp b/apps/settings/sub_menu/exam_mode_controller.cpp index 31a40c36a..33a853eaa 100644 --- a/apps/settings/sub_menu/exam_mode_controller.cpp +++ b/apps/settings/sub_menu/exam_mode_controller.cpp @@ -19,9 +19,6 @@ ExamModeController::ExamModeController(Responder * parentResponder) : m_cell{}, m_ledController(this), m_examModeModeController(this), -#if LEDS_CHOICE - m_ledColorCell(KDFont::LargeFont, KDFont::SmallFont), -#endif m_examModeCell(KDFont::LargeFont, KDFont::SmallFont) { for (int i = 0; i < k_maxNumberOfCells; i++) { @@ -38,14 +35,6 @@ bool ExamModeController::handleEvent(Ion::Events::Event event) { stack->push(&m_examModeModeController); return true; } -#if LEDS_CHOICE - else if (m_messageTreeModel->childAtIndex(selectedRow())->label() == I18n::Message::LEDColor) { - (&m_ledController)->setMessageTreeModel(m_messageTreeModel->childAtIndex(selectedRow())); - StackViewController * stack = stackController(); - stack->push(&m_ledController); - return true; - } -#endif else { AppsContainer::sharedAppsContainer()->displayExamModePopUp(examMode()); return true; @@ -79,11 +68,6 @@ int ExamModeController::numberOfRows() const { HighlightCell * ExamModeController::reusableCell(int index, int type) { assert(type == 0); assert(index >= 0 && index < 3); -#if LEDS_CHOICE - if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::LEDColor) { - return &m_ledColorCell; - } -#endif if (m_messageTreeModel->childAtIndex(index)->label() == I18n::Message::ExamModeMode) { return &m_examModeCell; } @@ -107,13 +91,6 @@ void ExamModeController::willDisplayCellForIndex(HighlightCell * cell, int index MessageTableCell * myCell = (MessageTableCell *)cell; myCell->setMessage(I18n::Message::ExamModeActive); } -#if LEDS_CHOICE - if (thisLabel == I18n::Message::LEDColor) { - MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; - I18n::Message message = (I18n::Message) m_messageTreeModel->childAtIndex(index)->childAtIndex((int)preferences->colorOfLED())->label(); - myTextCell->setSubtitle(message); - } -#endif if (thisLabel == I18n::Message::ExamModeMode) { MessageTableCellWithChevronAndMessage * myTextCell = (MessageTableCellWithChevronAndMessage *)cell; I18n::Message message = (I18n::Message) m_messageTreeModel->childAtIndex(index)->childAtIndex((uint8_t)GlobalPreferences::sharedGlobalPreferences()->tempExamMode() - 1)->label(); diff --git a/apps/settings/sub_menu/exam_mode_controller.h b/apps/settings/sub_menu/exam_mode_controller.h index e81563da3..e7abb1b12 100644 --- a/apps/settings/sub_menu/exam_mode_controller.h +++ b/apps/settings/sub_menu/exam_mode_controller.h @@ -30,9 +30,6 @@ private: MessageTableCell m_cell[k_maxNumberOfCells]; PreferencesController m_ledController; PreferencesController m_examModeModeController; -#if LEDS_CHOICE - MessageTableCellWithChevronAndMessage m_ledColorCell; -#endif MessageTableCellWithChevronAndMessage m_examModeCell; }; diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index 187782c3c..f95ae5eb2 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -107,43 +107,6 @@ Layout PreferencesController::layoutForPreferences(I18n::Message message) { ); } - // LED placeholders - case I18n::Message::ColorRed: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorWhite: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorBlue: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorGreen: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorYellow: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorPurple: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - case I18n::Message::ColorOrange: - { - const char * text = " "; - return LayoutHelper::String(text, strlen(text), k_layoutFont); - } - // Exam mode modes case I18n::Message::ExamModeModeStandard: { @@ -242,8 +205,6 @@ void PreferencesController::setPreferenceWithValueIndex(I18n::Message message, i preferences->setEditionMode((Preferences::EditionMode)valueIndex); } else if (message == I18n::Message::ComplexFormat) { preferences->setComplexFormat((Preferences::ComplexFormat)valueIndex); - } else if (message == I18n::Message::LEDColor) { - preferences->setColorOfLED((Preferences::LEDColor)valueIndex); } else if (message == I18n::Message::ExamModeMode) { GlobalPreferences::sharedGlobalPreferences()->setTempExamMode((GlobalPreferences::ExamMode)((uint8_t)valueIndex + 1)); } else if (message == I18n::Message::SymbolMultiplication) { @@ -269,11 +230,6 @@ int PreferencesController::valueIndexForPreference(I18n::Message message) const if (message == I18n::Message::ComplexFormat) { return (int)preferences->complexFormat(); } -#if LEDS_CHOICE - if (message == I18n::Message::LEDColor) { - return (int)preferences->colorOfLED(); - } -#endif if (message == I18n::Message::SymbolMultiplication) { return (int)preferences->symbolOfMultiplication(); } diff --git a/apps/shared.de.i18n b/apps/shared.de.i18n index 866e69355..09e4007e4 100644 --- a/apps/shared.de.i18n +++ b/apps/shared.de.i18n @@ -81,16 +81,8 @@ XStart = "X Startwert" Zoom = "Zoom" Developers = "Entwickler" BetaTesters = "Beta-Tester" -LEDColor = "LED Farbe" ExamModeMode = "Modus" ExamModeModeStandard = "Standard " ExamModeModeNoSym = "Ohne Symbole " ExamModeModeNoSymNoText = "Ohne Symbole & Text " ExamModeModeDutch = "Niederländisch " -ColorRed = "Rot " -ColorWhite = "Weiss " -ColorBlue = "Blau " -ColorGreen = "Grün " -ColorYellow = "Gelb " -ColorPurple = "Lila " -ColorOrange = "Orange " diff --git a/apps/shared.en.i18n b/apps/shared.en.i18n index 55f57a25c..b0992cddc 100644 --- a/apps/shared.en.i18n +++ b/apps/shared.en.i18n @@ -81,16 +81,8 @@ XStart = "X start" Zoom = "Zoom" Developers = "Developers" BetaTesters = "Beta testers" -LEDColor = "LED color" ExamModeMode = "Mode" ExamModeModeStandard = "Standard " ExamModeModeNoSym = "No sym " ExamModeModeNoSymNoText = "No sym no text " ExamModeModeDutch = "Dutch " -ColorRed = "Red " -ColorWhite = "White " -ColorBlue = "Blue " -ColorGreen = "Green " -ColorYellow = "Yellow " -ColorPurple = "Purple " -ColorOrange = "Orange " diff --git a/apps/shared.es.i18n b/apps/shared.es.i18n index 8257c8691..60559f351 100644 --- a/apps/shared.es.i18n +++ b/apps/shared.es.i18n @@ -81,16 +81,8 @@ XStart = "X inicio" Zoom = "Zoom" Developers = "Desarrolladores" BetaTesters = "Probadores beta" -LEDColor = "Color del LED" ExamModeMode = "Modo" ExamModeModeStandard = "Estándar " ExamModeModeNoSym = "Sin simbólico " ExamModeModeNoSymNoText = "sin simbolismo sin texto " ExamModeModeDutch = "Holandés " -ColorRed = "Rojo " -ColorWhite = "Blanco " -ColorBlue = "Azul " -ColorGreen = "Verde " -ColorYellow = "Amarillo " -ColorPurple = "Púrpura " -ColorOrange = "Naranja " diff --git a/apps/shared.fr.i18n b/apps/shared.fr.i18n index 32bb6aa3b..cb6af48fe 100644 --- a/apps/shared.fr.i18n +++ b/apps/shared.fr.i18n @@ -81,16 +81,8 @@ XStart = "X début" Zoom = "Zoom" Developers = "Développeurs" BetaTesters = "Beta testeurs" -LEDColor = "Couleur LED" ExamModeMode = "Mode" ExamModeModeStandard = "Standard " ExamModeModeNoSym = "Sans symbolique " ExamModeModeNoSymNoText = "Sans symbolique ni texte " ExamModeModeDutch = "Néerlandais " -ColorRed = "Rouge " -ColorWhite = "Blanc " -ColorBlue = "Bleu " -ColorGreen = "Vert " -ColorYellow = "Jaune " -ColorPurple = "Mauve " -ColorOrange = "Orange " diff --git a/apps/shared.hu.i18n b/apps/shared.hu.i18n index da5ec2157..5ed2a8dd0 100644 --- a/apps/shared.hu.i18n +++ b/apps/shared.hu.i18n @@ -81,16 +81,8 @@ XStart = "X kezdete" Zoom = "Zoom" Developers = "Fejlesztök" BetaTesters = "Béta tesztelök" -LEDColor = "LED szín" ExamModeMode = "Üzemmód" ExamModeModeStandard = "Normál" ExamModeModeNoSym = "Nincs sym" ExamModeModeNoSymNoText = "Nincs szimbolikus, nincs szöveg " ExamModeModeDutch = "Holland " -ColorRed = "Piros " -ColorWhite = "Fehér " -ColorBlue = "Kék " -ColorGreen = "Zöld " -ColorYellow = "Sárga " -ColorPurple = "Lila " -ColorOrange = "Narancssárga " diff --git a/apps/shared.it.i18n b/apps/shared.it.i18n index e480eed23..3abdfd8ce 100644 --- a/apps/shared.it.i18n +++ b/apps/shared.it.i18n @@ -81,16 +81,8 @@ XStart = "X iniziale" Zoom = "Zoom" Developers = "Developers" BetaTesters = "Beta testers" -LEDColor = "LED color" ExamModeMode = "Mode" ExamModeModeStandard = "Standard " ExamModeModeNoSym = "No sym " ExamModeModeNoSymNoText = "No sym no text " ExamModeModeDutch = "Dutch " -ColorRed = "Red " -ColorWhite = "White " -ColorBlue = "Blue " -ColorGreen = "Green " -ColorYellow = "Yellow " -ColorPurple = "Purple " -ColorOrange = "Orange " diff --git a/apps/shared.nl.i18n b/apps/shared.nl.i18n index 75d0e5cd7..5f13bc6ab 100644 --- a/apps/shared.nl.i18n +++ b/apps/shared.nl.i18n @@ -81,16 +81,8 @@ XStart = "X begin" Zoom = "Zoom" Developers = "Developers" BetaTesters = "Beta testers" -LEDColor = "LED color" ExamModeMode = "Mode" ExamModeModeStandard = "Standard " ExamModeModeNoSym = "No sym " ExamModeModeNoSymNoText = "No sym no text " ExamModeModeDutch = "Dutch " -ColorRed = "Red " -ColorWhite = "White " -ColorBlue = "Blue " -ColorGreen = "Green " -ColorYellow = "Yellow " -ColorPurple = "Purple " -ColorOrange = "Orange " diff --git a/apps/shared.pt.i18n b/apps/shared.pt.i18n index 84f6967d4..8d3306802 100644 --- a/apps/shared.pt.i18n +++ b/apps/shared.pt.i18n @@ -81,16 +81,8 @@ XStart = "X início" Zoom = "Zoom" Developers = "Desenvolvedores" BetaTesters = "Testadores beta" -LEDColor = "Cor LED" ExamModeMode = "Modo" ExamModeModeStandard = "Padrão " ExamModeModeNoSym = "Sem simbólico " ExamModeModeNoSymNoText = "Sem simbólico sem texto " ExamModeModeDutch = "Holandês " -ColorRed = "Vermelho " -ColorWhite = "Branco " -ColorBlue = "Azul " -ColorGreen = "Verde " -ColorYellow = "Amarelo " -ColorPurple = "Roxo " -ColorOrange = "Caranja " diff --git a/build/config.mak b/build/config.mak index 3b938123a..df389866f 100644 --- a/build/config.mak +++ b/build/config.mak @@ -14,4 +14,3 @@ EPSILON_TELEMETRY ?= 0 ESCHER_LOG_EVENTS_BINARY ?= 0 THEME_NAME ?= omega_light THEME_REPO ?= local -LEDS_CHOICE ?= 0 diff --git a/build/defaults.mak b/build/defaults.mak index e214ee555..0a77defd2 100644 --- a/build/defaults.mak +++ b/build/defaults.mak @@ -2,7 +2,6 @@ HOSTCC = gcc HOSTCXX = g++ PYTHON = python3 -SFLAGS += -DLEDS_CHOICE=$(LEDS_CHOICE) ifdef USERNAME SFLAGS += -DUSERNAME="$(USERNAME)" endif diff --git a/poincare/include/poincare/preferences.h b/poincare/include/poincare/preferences.h index 9ebbedc29..dd284ca10 100644 --- a/poincare/include/poincare/preferences.h +++ b/poincare/include/poincare/preferences.h @@ -37,15 +37,6 @@ public: Radian = 1, Gradian = 2 }; - enum class LEDColor : uint8_t { - Red = 0, - White = 1, - Green = 2, - Blue = 3, - Yellow = 4, - Purple = 5, - Orange = 6, - }; enum class SymbolMultiplication : uint8_t { Cross = 0, MiddleDot = 1, @@ -73,8 +64,6 @@ public: void setComplexFormat(Preferences::ComplexFormat complexFormat) { m_complexFormat = complexFormat; } uint8_t numberOfSignificantDigits() const { return m_numberOfSignificantDigits; } void setNumberOfSignificantDigits(uint8_t numberOfSignificantDigits) { m_numberOfSignificantDigits = numberOfSignificantDigits; } - LEDColor colorOfLED() const { return m_colorOfLED; } - void setColorOfLED(LEDColor color) { m_colorOfLED = color; } SymbolMultiplication symbolOfMultiplication() const { return m_symbolMultiplication; } void setSymbolMultiplication(SymbolMultiplication symbolOfMultiplication) { m_symbolMultiplication = symbolOfMultiplication; } SymbolFunction symbolOfFunction() const { return m_symbolFunction; } @@ -88,7 +77,6 @@ private: EditionMode m_editionMode; ComplexFormat m_complexFormat; uint8_t m_numberOfSignificantDigits; - LEDColor m_colorOfLED; SymbolMultiplication m_symbolMultiplication; SymbolFunction m_symbolFunction; PythonFont m_pythonFont; diff --git a/poincare/src/preferences.cpp b/poincare/src/preferences.cpp index 3cd35a5b6..0fde10705 100644 --- a/poincare/src/preferences.cpp +++ b/poincare/src/preferences.cpp @@ -13,7 +13,6 @@ Preferences::Preferences() : m_editionMode(EditionMode::Edition2D), m_complexFormat(Preferences::ComplexFormat::Real), m_numberOfSignificantDigits(PrintFloat::k_numberOfPrintedSignificantDigits), - m_colorOfLED(Preferences::LEDColor::Red), m_symbolMultiplication(Preferences::SymbolMultiplication::Auto), m_symbolFunction(Preferences::SymbolFunction::Default), m_pythonFont(Preferences::PythonFont::Large) From 7b07a2e3aca52467da9ae3e3865f77f85965178d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Guid=C3=A9e?= Date: Fri, 24 Jul 2020 08:24:12 +0200 Subject: [PATCH 17/28] [username] Change USERNAME to OMEGA_USERNAME --- README.md | 14 +++++++------- apps/Makefile | 2 +- apps/settings/main_controller.cpp | 2 +- apps/settings/main_controller.h | 2 +- apps/settings/sub_menu/about_controller.cpp | 2 +- apps/settings/sub_menu/about_controller.h | 2 +- build/config.mak | 2 +- build/defaults.mak | 4 ++-- docker/build | 4 ++-- ion/Makefile | 2 +- ion/include/ion.h | 2 +- ion/src/shared/platform_info.cpp | 8 ++++---- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 3d3a57b3b..cff8b3a2c 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git cd Omega git checkout omega-master make MODEL=n0100 clean -make MODEL=n0100 USERNAME="{Your name, max 15 characters}" -j4 +make MODEL=n0100 OMEGA_USERNAME="{Your name, max 15 characters}" -j4 make MODEL=n0100 epsilon_flash ``` @@ -58,7 +58,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git cd Omega git checkout omega-master make clean -make USERNAME="{Your name, max 15 characters}" -j4 +make OMEGA_USERNAME="{Your name, max 15 characters}" -j4 make epsilon_flash ``` @@ -77,10 +77,10 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git cd Omega git checkout omega-master make clean -make MODEL=n0100 USERNAME="" -j8 -make MODEL=n0100 USERNAME="" binpack -j8 -make USERNAME="" -j8 -make USERNAME="" binpack -j8 +make MODEL=n0100 OMEGA_USERNAME="" -j8 +make MODEL=n0100 OMEGA_USERNAME="" binpack -j8 +make OMEGA_USERNAME="" -j8 +make OMEGA_USERNAME="" binpack -j8 ``` Important: Don't forget the `--recursive` tag, because Omega relies on submodules. @@ -108,7 +108,7 @@ git clone --recursive https://github.com/Omega-Numworks/Omega.git cd Omega git checkout omega-master make clean -make PLATFORM=simulator TARGET=web USERNAME="{Your name, max 15 characters}" -j4 +make PLATFORM=simulator TARGET=web OMEGA_USERNAME="{Your name, max 15 characters}" -j4 ``` The simulator is now in `output/release/simulator/web/simulator.zip` diff --git a/apps/Makefile b/apps/Makefile index 381c0d7d2..cc6c6ff70 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -51,7 +51,7 @@ snapshots_count = $(words $(apps)) snapshot_includes = $(foreach i,$(app_headers),-include $(i) ) epsilon_app_names = '$(foreach i,${apps_list},"$(i)", )' -$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DUSERNAME="$(USERNAME)" +$(call object_for,apps/apps_container_storage.cpp apps/apps_container.cpp apps/main.cpp): CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) -DOMEGA_USERNAME="$(OMEGA_USERNAME)" # I18n file generation diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index 02f17f1dd..b9f51cdc1 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -19,7 +19,7 @@ constexpr SettingsMessageTree s_modelMathOptionsChildren[6] = {SettingsMessageTr constexpr SettingsMessageTree s_modelFontChildren[2] = {SettingsMessageTree(I18n::Message::LargeFont), SettingsMessageTree(I18n::Message::SmallFont)}; constexpr SettingsMessageTree s_accessibilityChildren[6] = {SettingsMessageTree(I18n::Message::AccessibilityInvertColors), SettingsMessageTree(I18n::Message::AccessibilityMagnify),SettingsMessageTree(I18n::Message::AccessibilityGamma),SettingsMessageTree(I18n::Message::AccessibilityGammaRed),SettingsMessageTree(I18n::Message::AccessibilityGammaGreen),SettingsMessageTree(I18n::Message::AccessibilityGammaBlue)}; constexpr SettingsMessageTree s_contributorsChildren[20] = {SettingsMessageTree(I18n::Message::Developers), SettingsMessageTree(I18n::Message::QuentinGuidee), SettingsMessageTree(I18n::Message::SandraSimmons), SettingsMessageTree(I18n::Message::JoachimLeFournis), SettingsMessageTree(I18n::Message::JeanBaptisteBoric), SettingsMessageTree(I18n::Message::MaximeFriess), SettingsMessageTree(I18n::Message::David), SettingsMessageTree(I18n::Message::DamienNicolet), SettingsMessageTree(I18n::Message::EvannDreumont), SettingsMessageTree(I18n::Message::SzaboLevente), SettingsMessageTree(I18n::Message::VenceslasDuet), SettingsMessageTree(I18n::Message::CharlotteThomas), SettingsMessageTree(I18n::Message::AntoninLoubiere), SettingsMessageTree(I18n::Message::BetaTesters), SettingsMessageTree(I18n::Message::CyprienMejat), SettingsMessageTree(I18n::Message::TimeoArnouts), SettingsMessageTree(I18n::Message::JulieC), SettingsMessageTree(I18n::Message::LelahelHideux), SettingsMessageTree(I18n::Message::Madil), SettingsMessageTree(I18n::Message::HilaireLeRoux)}; -#ifdef USERNAME +#ifdef OMEGA_USERNAME constexpr SettingsMessageTree s_modelAboutChildren[8] = {SettingsMessageTree(I18n::Message::Username), SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)}; #else constexpr SettingsMessageTree s_modelAboutChildren[7] = {SettingsMessageTree(I18n::Message::SoftwareVersion), SettingsMessageTree(I18n::Message::OmegaVersion), SettingsMessageTree(I18n::Message::MicroPythonVersion), SettingsMessageTree(I18n::Message::MemUse), SettingsMessageTree(I18n::Message::SerialNumber), SettingsMessageTree(I18n::Message::FccId), SettingsMessageTree(I18n::Message::Contributors, s_contributorsChildren)}; diff --git a/apps/settings/main_controller.h b/apps/settings/main_controller.h index 62f1d3c36..25c30cf9c 100644 --- a/apps/settings/main_controller.h +++ b/apps/settings/main_controller.h @@ -23,7 +23,7 @@ extern const Shared::SettingsMessageTree s_modelMathOptionsChildren[6]; extern const Shared::SettingsMessageTree s_modelFontChildren[2]; extern const Shared::SettingsMessageTree s_accessibilityChildren[6]; extern const Shared::SettingsMessageTree s_contributorsChildren[20]; -#ifdef USERNAME +#ifdef OMEGA_USERNAME extern const Shared::SettingsMessageTree s_modelAboutChildren[8]; #else extern const Shared::SettingsMessageTree s_modelAboutChildren[7]; diff --git a/apps/settings/sub_menu/about_controller.cpp b/apps/settings/sub_menu/about_controller.cpp index fe64d7453..54162bfe5 100644 --- a/apps/settings/sub_menu/about_controller.cpp +++ b/apps/settings/sub_menu/about_controller.cpp @@ -142,7 +142,7 @@ void AboutController::willDisplayCellForIndex(HighlightCell * cell, int index) { MessageTableCellWithBuffer * myCell = (MessageTableCellWithBuffer *)cell; static const char * mpVersion = MICROPY_VERSION_STRING; static const char * messages[] = { -#ifdef USERNAME +#ifdef OMEGA_USERNAME Ion::username(), #endif Ion::softwareVersion(), diff --git a/apps/settings/sub_menu/about_controller.h b/apps/settings/sub_menu/about_controller.h index 5824432bc..e94a6e2aa 100644 --- a/apps/settings/sub_menu/about_controller.h +++ b/apps/settings/sub_menu/about_controller.h @@ -21,7 +21,7 @@ public: void willDisplayCellForIndex(HighlightCell * cell, int index) override; int typeAtLocation(int i, int j) override; private: -#ifdef USERNAME +#ifdef OMEGA_USERNAME constexpr static int k_totalNumberOfCell = 8; #else constexpr static int k_totalNumberOfCell = 7; diff --git a/build/config.mak b/build/config.mak index df389866f..5b10a4b3b 100644 --- a/build/config.mak +++ b/build/config.mak @@ -6,7 +6,7 @@ DEBUG ?= 0 HOME_DISPLAY_EXTERNALS ?= 1 EPSILON_VERSION ?= 14.4.1 OMEGA_VERSION ?= 1.20.1 -# USERNAME ?= N/A +# OMEGA_USERNAME ?= N/A EPSILON_APPS ?= calculation rpn graph code statistics probability solver atom sequence regression settings external EPSILON_I18N ?= en fr nl pt it de es hu EPSILON_GETOPT ?= 0 diff --git a/build/defaults.mak b/build/defaults.mak index 0a77defd2..11a7f9edd 100644 --- a/build/defaults.mak +++ b/build/defaults.mak @@ -2,8 +2,8 @@ HOSTCC = gcc HOSTCXX = g++ PYTHON = python3 -ifdef USERNAME - SFLAGS += -DUSERNAME="$(USERNAME)" +ifdef OMEGA_USERNAME + SFLAGS += -DOMEGA_USERNAME="$(OMEGA_USERNAME)" endif SFLAGS += -DEPSILON_GETOPT=$(EPSILON_GETOPT) SFLAGS += -DEPSILON_TELEMETRY=$(EPSILON_TELEMETRY) diff --git a/docker/build b/docker/build index e5f0b1510..e46c7cfd7 100644 --- a/docker/build +++ b/docker/build @@ -4,10 +4,10 @@ set -e REPO="${1:-https://github.com/Omega-Numworks/Omega.git}" BRANCH="${2:-master}" MODEL="${3:-MODEL=n0110}" -USERNAME="${4:- }" +OMEGA_USERNAME="${4:- }" OPTIONS="${5:-epsilon_flash}" echo Building ${REPO} branch ${BRANCH} for ${MODEL} with options ${OPTIONS} ! git clone --recurse-submodules -j $(nproc) --depth 1 --branch ${BRANCH} ${REPO} omega -time make cleanall && time make -j $(nproc) -C omega ${MODEL} ${USERNAME} ${OPTIONS} \ No newline at end of file +time make cleanall && time make -j $(nproc) -C omega ${MODEL} ${OMEGA_USERNAME} ${OPTIONS} \ No newline at end of file diff --git a/ion/Makefile b/ion/Makefile index 4900217e9..2722be3e4 100644 --- a/ion/Makefile +++ b/ion/Makefile @@ -20,7 +20,7 @@ include ion/src/shared/tools/Makefile # char test[4]= "ab"; is valid and should initialize test to 'a','b',0,0). # Older versions of GCC are not conformant so we resort to an initializer list. initializer_list = $(shell echo $(1) | sed "s/\(.\)/'\1',/g")0 -$(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))" -DOMEGA_VERSION="$(call initializer_list,$(OMEGA_VERSION))" -DUSERNAME="$(call initializer_list,$(USERNAME))" +$(call object_for,ion/src/shared/platform_info.cpp): SFLAGS += -DPATCH_LEVEL="$(call initializer_list,$(PATCH_LEVEL))" -DEPSILON_VERSION="$(call initializer_list,$(EPSILON_VERSION))" -DOMEGA_VERSION="$(call initializer_list,$(OMEGA_VERSION))" -DOMEGA_USERNAME="$(call initializer_list,$(OMEGA_USERNAME))" ion_src += $(addprefix ion/src/shared/, \ console_display.cpp:+consoledisplay \ diff --git a/ion/include/ion.h b/ion/include/ion.h index 9541b6777..2921da4a4 100644 --- a/ion/include/ion.h +++ b/ion/include/ion.h @@ -30,7 +30,7 @@ void ion_main(int argc, const char * const argv[]); namespace Ion { const char * serialNumber(); -#ifdef USERNAME +#ifdef OMEGA_USERNAME const char * username(); #endif const char * softwareVersion(); diff --git a/ion/src/shared/platform_info.cpp b/ion/src/shared/platform_info.cpp index 053f60d73..84d5937ca 100644 --- a/ion/src/shared/platform_info.cpp +++ b/ion/src/shared/platform_info.cpp @@ -33,8 +33,8 @@ public: m_footer(Magic), m_ohm_header(OmegaMagic), m_omegaVersion{OMEGA_VERSION}, -#ifdef USERNAME - m_username{USERNAME}, +#ifdef OMEGA_USERNAME + m_username{OMEGA_USERNAME}, #else m_username{"\0"}, #endif @@ -57,7 +57,7 @@ public: assert(m_ohm_footer == OmegaMagic); return m_omegaVersion; } -#ifdef USERNAME +#ifdef OMEGA_USERNAME const char * username() const { assert(m_storageAddress != nullptr); assert(m_storageSize != 0); @@ -102,7 +102,7 @@ const char * Ion::omegaVersion() { return platform_infos.omegaVersion(); } -#ifdef USERNAME +#ifdef OMEGA_USERNAME const char * Ion::username() { return platform_infos.username(); } From 93f4281bdc9ab378f06bb889d3237748b9de8fce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Guid=C3=A9e?= Date: Fri, 24 Jul 2020 09:05:01 +0200 Subject: [PATCH 18/28] [themes] Update submodule --- themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes b/themes index d9bc63ee6..48fc1cc72 160000 --- a/themes +++ b/themes @@ -1 +1 @@ -Subproject commit d9bc63ee68351e2f57cbab3edcdeeca8e077c7df +Subproject commit 48fc1cc72739ad766abbf161d78c2f98cf2f797d From c57f8d257bf6f335d63fafd1197d581508c9b882 Mon Sep 17 00:00:00 2001 From: Joachim LF Date: Mon, 27 Jul 2020 16:41:01 +0200 Subject: [PATCH 19/28] [Apps/home] Change menu behaviour with incomplete lines --- apps/home/controller.cpp | 14 ++++++++++++-- escher/include/escher/selectable_table_view.h | 2 +- escher/src/selectable_table_view.cpp | 18 +++++++++--------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 2faa2e488..9ba0ee2c2 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -110,6 +110,17 @@ bool Controller::handleEvent(Ion::Events::Event event) { return true; } + if((numberOfIcons() % k_numberOfColumns) + && event == Ion::Events::Down + && selectionDataSource()->selectedRow() == numberOfRows() - 2 + && (numberOfIcons() % k_numberOfColumns) <= selectionDataSource()->selectedColumn()){ + return m_view.selectableTableView()->selectCellAtLocation(numberOfIcons() % k_numberOfColumns - 1, numberOfRows()-1); + } + + if(m_view.selectableTableView()->handleEvent(event, false)){ + return true; + } + if (event == Ion::Events::Home || event == Ion::Events::Back) { return m_view.selectableTableView()->selectCellAtLocation(0,0); } @@ -126,9 +137,8 @@ bool Controller::handleEvent(Ion::Events::Event event) { void Controller::didBecomeFirstResponder() { if (selectionDataSource()->selectedRow() == -1) { - selectionDataSource()->selectCellAtLocation(0, 0); + m_view.selectableTableView()->selectCellAtLocation(0, 0, false); } - Container::activeApp()->setFirstResponder(m_view.selectableTableView()); } void Controller::viewWillAppear() { diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index 6e4fb7ac0..23994cdfa 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -25,7 +25,7 @@ public: void selectRow(int j); void selectColumn(int i); void reloadData(bool setFirstResponder = true); - bool handleEvent(Ion::Events::Event event) override; + bool handleEvent(Ion::Events::Event event, bool setFirstResponder = true); void didEnterResponderChain(Responder * previousFirstResponder) override; void willExitResponderChain(Responder * nextFirstResponder) override; void deselectTable(bool withinTemporarySelection = false); diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index 27f4bd395..0b92f7502 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -132,30 +132,30 @@ HighlightCell * SelectableTableView::selectedCell() { return cellAtLocation(selectedColumn(), selectedRow()); } -bool SelectableTableView::handleEvent(Ion::Events::Event event) { +bool SelectableTableView::handleEvent(Ion::Events::Event event, bool setFirstResponder) { if (event == Ion::Events::Down) { - return selectCellAtLocation(selectedColumn(), selectedRow()+1); + return selectCellAtLocation(selectedColumn(), selectedRow()+1, setFirstResponder); } if ((event == Ion::Events::ShiftDown || event == Ion::Events::AlphaDown) && selectedRow() < dataSource()->numberOfRows()-1) { - return selectCellAtLocation(selectedColumn(), dataSource()->numberOfRows()-1); + return selectCellAtLocation(selectedColumn(), dataSource()->numberOfRows()-1, setFirstResponder); } if (event == Ion::Events::Up) { - return selectCellAtLocation(selectedColumn(), selectedRow()-1); + return selectCellAtLocation(selectedColumn(), selectedRow()-1, setFirstResponder); } if ((event == Ion::Events::ShiftUp || event == Ion::Events::AlphaUp) && selectedRow() > 0) { - return selectCellAtLocation(selectedColumn(), 0); + return selectCellAtLocation(selectedColumn(), 0, setFirstResponder); } if (event == Ion::Events::Left) { - return selectCellAtLocation(selectedColumn()-1, selectedRow()); + return selectCellAtLocation(selectedColumn()-1, selectedRow(), setFirstResponder); } if ((event == Ion::Events::ShiftLeft || event == Ion::Events::AlphaLeft) && selectedColumn() > 0) { - return selectCellAtLocation(0, selectedRow()); + return selectCellAtLocation(0, selectedRow(), setFirstResponder); } if (event == Ion::Events::Right) { - return selectCellAtLocation(selectedColumn()+1, selectedRow()); + return selectCellAtLocation(selectedColumn()+1, selectedRow(), setFirstResponder); } if ((event == Ion::Events::ShiftRight || event == Ion::Events::AlphaRight) && selectedColumn() < dataSource()->numberOfColumns()-1) { - return selectCellAtLocation(dataSource()->numberOfColumns()-1, selectedRow()); + return selectCellAtLocation(dataSource()->numberOfColumns()-1, selectedRow(), setFirstResponder); } if (event == Ion::Events::Copy || event == Ion::Events::Cut) { HighlightCell * cell = selectedCell(); From b4a3dd10e12d4dc74780bbc360289f806e8152d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 28 Jul 2020 16:30:04 +0200 Subject: [PATCH 20/28] [apps/shared] ToolBoxHelpers: don't overflow buffer If the commandLength is > than the buffer size, we have to escape at some point to avoid overflowing the buffer. --- apps/shared/toolbox_helpers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/shared/toolbox_helpers.cpp b/apps/shared/toolbox_helpers.cpp index 8758ca763..fc16a0544 100644 --- a/apps/shared/toolbox_helpers.cpp +++ b/apps/shared/toolbox_helpers.cpp @@ -41,7 +41,7 @@ void TextToInsertForCommandText(const char * command, int commandLength, char * UTF8Decoder decoder(command); CodePoint codePoint = decoder.nextCodePoint(); - while (codePoint != UCodePointNull && (commandLength < 0 || (decoder.stringPosition() - command <= commandLength))) { + while (codePoint != UCodePointNull && index < bufferSize - 1 && (commandLength < 0 || (decoder.stringPosition() - command <= commandLength))) { if (codePoint == ')') { numberOfOpenParentheses--; } else if (codePoint == ']') { From d37bf9e3447cbd663efa0481d4be992ae8ea3bd0 Mon Sep 17 00:00:00 2001 From: Joachim LF Date: Sat, 25 Jul 2020 15:28:30 +0200 Subject: [PATCH 21/28] [Apps/Shared] Fixed interval and curve view exit --- .../interactive_curve_view_controller.cpp | 4 ++- .../interactive_curve_view_controller.h | 6 +++- apps/shared/interval.cpp | 33 +++++-------------- apps/shared/interval.h | 29 +++++++++------- apps/shared/interval_parameter_controller.cpp | 22 +++++++++---- apps/shared/interval_parameter_controller.h | 2 +- apps/shared/range_parameter_controller.cpp | 25 ++++++++++---- apps/shared/range_parameter_controller.h | 3 ++ 8 files changed, 73 insertions(+), 51 deletions(-) diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index 6daeacea0..c6b736296 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -15,8 +15,10 @@ InteractiveCurveViewController::InteractiveCurveViewController(Responder * paren m_rangeVersion(rangeVersion), m_rangeParameterController(this, inputEventHandlerDelegate, interactiveRange), m_zoomParameterController(this, interactiveRange, curveView), + m_interactiveRange(interactiveRange), m_rangeButton(this, I18n::Message::Axis, Invocation([](void * context, void * sender) { InteractiveCurveViewController * graphController = (InteractiveCurveViewController *) context; + graphController->rangeParameterController()->setRange(graphController->interactiveRange()); StackViewController * stack = graphController->stackController(); stack->push(graphController->rangeParameterController()); return true; @@ -113,7 +115,7 @@ void InteractiveCurveViewController::didBecomeFirstResponder() { } } -ViewController * InteractiveCurveViewController::rangeParameterController() { +RangeParameterController * InteractiveCurveViewController::rangeParameterController() { return &m_rangeParameterController; } diff --git a/apps/shared/interactive_curve_view_controller.h b/apps/shared/interactive_curve_view_controller.h index c732ff524..6fbb1ca29 100644 --- a/apps/shared/interactive_curve_view_controller.h +++ b/apps/shared/interactive_curve_view_controller.h @@ -19,7 +19,7 @@ public: void didBecomeFirstResponder() override; TELEMETRY_ID("Graph"); - ViewController * rangeParameterController(); + RangeParameterController * rangeParameterController(); ViewController * zoomParameterController(); virtual ViewController * initialisationParameterController() = 0; @@ -35,6 +35,7 @@ public: void willExitResponderChain(Responder * nextFirstResponder) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; + protected: Responder * tabController() const; virtual StackViewController * stackController() const; @@ -57,6 +58,8 @@ protected: float cursorBottomMarginRatio() override; OkView m_okView; + + InteractiveCurveViewRange * interactiveRange(){return m_interactiveRange;} private: /* The value 21 is the actual height of the ButtonRow, that is * ButtonRowController::ContentView::k_plainStyleHeight + 1. @@ -75,6 +78,7 @@ private: uint32_t * m_rangeVersion; RangeParameterController m_rangeParameterController; ZoomParameterController m_zoomParameterController; + InteractiveCurveViewRange * m_interactiveRange; Button m_rangeButton; Button m_zoomButton; Button m_defaultInitialisationButton; diff --git a/apps/shared/interval.cpp b/apps/shared/interval.cpp index 4754feb3d..501df7e87 100644 --- a/apps/shared/interval.cpp +++ b/apps/shared/interval.cpp @@ -29,21 +29,6 @@ double Interval::element(int i) { return m_intervalBuffer[i]; } -void Interval::setStart(double f) { - m_start = f; - m_needCompute = true; -} - -void Interval::setEnd(double f) { - m_end = f; - m_needCompute = true; -} - -void Interval::setStep(double f) { - m_step = f; - m_needCompute = true; -} - void Interval::setElement(int i, double f) { assert(i <= numberOfElements() && i < k_maxNumberOfElements); computeElements(); @@ -54,16 +39,16 @@ void Interval::setElement(int i, double f) { } void Interval::reset() { - m_start = 0.0; - m_end = 10.0; - m_step = 1.0; + m_parameters.setStart(0.0); + m_parameters.setEnd(10.0); + m_parameters.setStep(1.0); m_needCompute = true; } void Interval::clear() { - m_start = 1.0; - m_end = 0.0; - m_step = 1.0; + m_parameters.setStart(1.0); + m_parameters.setEnd(10.0); + m_parameters.setStep(1.0); m_needCompute = true; } @@ -71,14 +56,14 @@ void Interval::computeElements() { if (!m_needCompute) { return; } - if (m_start > m_end) { + if (m_parameters.start() > m_parameters.end()) { m_numberOfElements = 0; } else { - m_numberOfElements = m_step > 0 ? 1 + (m_end - m_start)/m_step : k_maxNumberOfElements; + m_numberOfElements = m_parameters.step() > 0 ? 1 + (m_parameters.end() - m_parameters.start())/m_parameters.step() : k_maxNumberOfElements; m_numberOfElements = m_numberOfElements > k_maxNumberOfElements || m_numberOfElements < 0 ? k_maxNumberOfElements : m_numberOfElements; } for (int i = 0; i < m_numberOfElements; i += 1) { - m_intervalBuffer[i] = m_start + i * m_step; + m_intervalBuffer[i] = m_parameters.start() + i * m_parameters.step(); } m_needCompute = false; } diff --git a/apps/shared/interval.h b/apps/shared/interval.h index 3be28dc93..6db4faa68 100644 --- a/apps/shared/interval.h +++ b/apps/shared/interval.h @@ -10,13 +10,22 @@ public: Interval(const Interval&) = delete; int numberOfElements(); void deleteElementAtIndex(int index); + class intervalParameters { + public: + void setStart(double f) { m_start = f; } + void setEnd(double f) { m_end = f; } + void setStep(double f) {m_step = f; } + double start() const { return m_start; } + double end() const { return m_end; } + double step() const { return m_step; } + private: + double m_start; + double m_end; + double m_step; + }; double element(int i); - double start() const { return m_start; } - double end() const { return m_end; } - double step() const { return m_step; } - void setStart(double f); - void setEnd(double f); - void setStep(double f); + intervalParameters * parameters() { return &m_parameters; } + void setParameters(intervalParameters parameters) { m_parameters = parameters; } void setElement(int i, double f); void forceRecompute(){ m_needCompute = true;} void reset(); @@ -27,14 +36,12 @@ private: void computeElements(); int m_numberOfElements; double m_intervalBuffer[k_maxNumberOfElements]; - double m_start; - double m_end; - double m_step; bool m_needCompute; + intervalParameters m_parameters; }; -typedef void (Interval::*SetterPointer)(double); -typedef double (Interval::*GetterPointer)() const; +typedef void (Interval::intervalParameters::*SetterPointer)(double); +typedef double (Interval::intervalParameters::*GetterPointer)() const; } diff --git a/apps/shared/interval_parameter_controller.cpp b/apps/shared/interval_parameter_controller.cpp index cc8a41bca..dc34e34d3 100644 --- a/apps/shared/interval_parameter_controller.cpp +++ b/apps/shared/interval_parameter_controller.cpp @@ -2,6 +2,8 @@ namespace Shared { +static Interval::intervalParameters s_tempIntevalParameters; + IntervalParameterController::IntervalParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) : FloatParameterController(parentResponder), m_interval(nullptr), @@ -16,6 +18,11 @@ IntervalParameterController::IntervalParameterController(Responder * parentRespo } } +void IntervalParameterController::setInterval(Interval * interval) { + m_interval = interval; + s_tempIntevalParameters = *(*interval).parameters(); +} + const char * IntervalParameterController::title() { return I18n::translate(m_title); } @@ -42,8 +49,8 @@ void IntervalParameterController::willDisplayCellForIndex(HighlightCell * cell, } double IntervalParameterController::parameterAtIndex(int index) { - GetterPointer getters[k_totalNumberOfCell] = {&Interval::start, &Interval::end, &Interval::step}; - return (m_interval->*getters[index])(); + GetterPointer getters[k_totalNumberOfCell] = {&Shared::Interval::intervalParameters::start, &Shared::Interval::intervalParameters::end, &Shared::Interval::intervalParameters::step}; + return (s_tempIntevalParameters.*getters[index])(); } bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double f) { @@ -51,18 +58,18 @@ bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } - double start = parameterIndex == 0 ? f : m_interval->start(); - double end = parameterIndex == 1 ? f : m_interval->end(); + double start = parameterIndex == 0 ? f : s_tempIntevalParameters.start(); + double end = parameterIndex == 1 ? f : s_tempIntevalParameters.end(); if (start > end) { if (parameterIndex == 1) { Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } double g = f+1.0; - m_interval->setEnd(g); + s_tempIntevalParameters.setEnd(g); } - SetterPointer setters[k_totalNumberOfCell] = {&Interval::setStart, &Interval::setEnd, &Interval::setStep}; - (m_interval->*setters[parameterIndex])(f); + SetterPointer setters[k_totalNumberOfCell] = {&Shared::Interval::intervalParameters::setStart, &Shared::Interval::intervalParameters::setEnd, &Shared::Interval::intervalParameters::setStep}; + (s_tempIntevalParameters.*setters[parameterIndex])(f); return true; } @@ -85,6 +92,7 @@ int IntervalParameterController::reusableParameterCellCount(int type) { } void IntervalParameterController::buttonAction() { + m_interval->setParameters(s_tempIntevalParameters); m_interval->forceRecompute(); StackViewController * stack = stackController(); stack->pop(); diff --git a/apps/shared/interval_parameter_controller.h b/apps/shared/interval_parameter_controller.h index 9ed10d99b..05d511c9a 100644 --- a/apps/shared/interval_parameter_controller.h +++ b/apps/shared/interval_parameter_controller.h @@ -12,7 +12,7 @@ class IntervalParameterController : public Shared::FloatParameterController(parentResponder), m_interactiveRange(interactiveRange), + m_tempInteractiveRange(*interactiveRange), m_xRangeCells{}, m_yRangeCells{}, m_yAutoCell(I18n::Message::YAuto) @@ -18,7 +19,7 @@ RangeParameterController::RangeParameterController(Responder * parentResponder, } for (int i = 0; i < k_numberOfConvertibleTextCell; i++) { m_yRangeCells[i].setParentResponder(&m_selectableTableView); - m_yRangeCells[i].setInteractiveCurveViewRange(m_interactiveRange); + m_yRangeCells[i].setInteractiveCurveViewRange(&m_tempInteractiveRange); m_yRangeCells[i].textField()->setDelegates(inputEventHandlerDelegate, this); } } @@ -50,13 +51,13 @@ void RangeParameterController::willDisplayCellForIndex(HighlightCell * cell, int } if (index == 2) { SwitchView * switchView = (SwitchView *)m_yAutoCell.accessoryView(); - switchView->setState(m_interactiveRange->yAuto()); + switchView->setState(m_tempInteractiveRange.yAuto()); return; } MessageTableCellWithEditableText * myCell = (MessageTableCellWithEditableText *)cell; I18n::Message labels[k_numberOfTextCell+1] = {I18n::Message::XMin, I18n::Message::XMax, I18n::Message::Default, I18n::Message::YMin, I18n::Message::YMax}; myCell->setMessage(labels[index]); - KDColor yColor = m_interactiveRange->yAuto() ? Palette::GreyDark : KDColorBlack; + KDColor yColor = m_tempInteractiveRange.yAuto() ? Palette::GreyDark : KDColorBlack; KDColor colors[k_numberOfTextCell+1] = {KDColorBlack, KDColorBlack, KDColorBlack, yColor, yColor}; myCell->setTextColor(colors[index]); FloatParameterController::willDisplayCellForIndex(cell, index); @@ -70,9 +71,14 @@ bool RangeParameterController::textFieldDidFinishEditing(TextField * textField, return false; } +void RangeParameterController::setRange(InteractiveCurveViewRange * range){ + m_interactiveRange = range; + m_tempInteractiveRange = *range; +} + bool RangeParameterController::handleEvent(Ion::Events::Event event) { if (activeCell() == 2 && (event == Ion::Events::OK || event == Ion::Events::EXE)) { - m_interactiveRange->setYAuto(!m_interactiveRange->yAuto()); + m_tempInteractiveRange.setYAuto(!m_tempInteractiveRange.yAuto()); m_selectableTableView.reloadData(); return true; } @@ -83,14 +89,14 @@ float RangeParameterController::parameterAtIndex(int parameterIndex) { ParameterGetterPointer getters[k_numberOfTextCell] = {&InteractiveCurveViewRange::xMin, &InteractiveCurveViewRange::xMax, &InteractiveCurveViewRange::yMin, &InteractiveCurveViewRange::yMax}; int index = parameterIndex > 2 ? parameterIndex - 1 : parameterIndex; - return (m_interactiveRange->*getters[index])(); + return (m_tempInteractiveRange.*getters[index])(); } bool RangeParameterController::setParameterAtIndex(int parameterIndex, float f) { ParameterSetterPointer setters[k_numberOfTextCell] = {&InteractiveCurveViewRange::setXMin, &InteractiveCurveViewRange::setXMax, &InteractiveCurveViewRange::setYMin, &InteractiveCurveViewRange::setYMax}; int index = parameterIndex > 2 ? parameterIndex - 1 : parameterIndex; - (m_interactiveRange->*setters[index])(f); + (m_tempInteractiveRange.*setters[index])(f); return true; } @@ -119,4 +125,11 @@ int RangeParameterController::reusableParameterCellCount(int type) { return k_numberOfConvertibleTextCell; } +void RangeParameterController::buttonAction() { + *m_interactiveRange = m_tempInteractiveRange; + StackViewController * stack = stackController(); + stack->pop(); +} + + } diff --git a/apps/shared/range_parameter_controller.h b/apps/shared/range_parameter_controller.h index 250ba0ce8..8c5a1ae95 100644 --- a/apps/shared/range_parameter_controller.h +++ b/apps/shared/range_parameter_controller.h @@ -16,6 +16,7 @@ public: void willDisplayCellForIndex(HighlightCell * cell, int index) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; bool handleEvent(Ion::Events::Event event) override; + void setRange(InteractiveCurveViewRange * range); TELEMETRY_ID("Range"); private: class MessageTableCellWithConvertibleEditableText : public MessageTableCellWithEditableText { @@ -39,9 +40,11 @@ private: constexpr static int k_numberOfConvertibleTextCell = 2; constexpr static int k_numberOfTextCell = k_numberOfEditableTextCell+k_numberOfConvertibleTextCell; InteractiveCurveViewRange * m_interactiveRange; + InteractiveCurveViewRange m_tempInteractiveRange; MessageTableCellWithEditableText m_xRangeCells[k_numberOfEditableTextCell]; MessageTableCellWithConvertibleEditableText m_yRangeCells[k_numberOfConvertibleTextCell]; MessageTableCellWithSwitch m_yAutoCell; + void buttonAction() override; }; } From 61792058d3adfafe840eb8eec3ba0d2ef5d3afa6 Mon Sep 17 00:00:00 2001 From: Hugo Saint-Vignes Date: Mon, 27 Jul 2020 14:06:30 +0200 Subject: [PATCH 22/28] [apps/shared] Fix typos for Interval and curve view temporary params Change-Id: I610726ed5966d353397be923b76dd003297940a7 --- .../interactive_curve_view_controller.h | 4 +-- apps/shared/interval.cpp | 2 +- apps/shared/interval.h | 34 +++++++++---------- apps/shared/interval_parameter_controller.cpp | 25 ++++++++------ apps/shared/interval_parameter_controller.h | 1 + apps/shared/range_parameter_controller.cpp | 1 - apps/shared/range_parameter_controller.h | 2 +- 7 files changed, 36 insertions(+), 33 deletions(-) diff --git a/apps/shared/interactive_curve_view_controller.h b/apps/shared/interactive_curve_view_controller.h index 6fbb1ca29..99927b65a 100644 --- a/apps/shared/interactive_curve_view_controller.h +++ b/apps/shared/interactive_curve_view_controller.h @@ -57,9 +57,9 @@ protected: // SimpleInteractiveCurveViewController float cursorBottomMarginRatio() override; - OkView m_okView; + InteractiveCurveViewRange * interactiveRange() { return m_interactiveRange; } - InteractiveCurveViewRange * interactiveRange(){return m_interactiveRange;} + OkView m_okView; private: /* The value 21 is the actual height of the ButtonRow, that is * ButtonRowController::ContentView::k_plainStyleHeight + 1. diff --git a/apps/shared/interval.cpp b/apps/shared/interval.cpp index 501df7e87..1fccb9e81 100644 --- a/apps/shared/interval.cpp +++ b/apps/shared/interval.cpp @@ -47,7 +47,7 @@ void Interval::reset() { void Interval::clear() { m_parameters.setStart(1.0); - m_parameters.setEnd(10.0); + m_parameters.setEnd(0.0); m_parameters.setStep(1.0); m_needCompute = true; } diff --git a/apps/shared/interval.h b/apps/shared/interval.h index 6db4faa68..95c269d68 100644 --- a/apps/shared/interval.h +++ b/apps/shared/interval.h @@ -10,22 +10,22 @@ public: Interval(const Interval&) = delete; int numberOfElements(); void deleteElementAtIndex(int index); - class intervalParameters { - public: - void setStart(double f) { m_start = f; } - void setEnd(double f) { m_end = f; } - void setStep(double f) {m_step = f; } - double start() const { return m_start; } - double end() const { return m_end; } - double step() const { return m_step; } - private: - double m_start; - double m_end; - double m_step; + class IntervalParameters { + public: + void setStart(double f) { m_start = f; } + void setEnd(double f) { m_end = f; } + void setStep(double f) { m_step = f; } + double start() const { return m_start; } + double end() const { return m_end; } + double step() const { return m_step; } + private: + double m_start; + double m_end; + double m_step; }; double element(int i); - intervalParameters * parameters() { return &m_parameters; } - void setParameters(intervalParameters parameters) { m_parameters = parameters; } + IntervalParameters * parameters() { return &m_parameters; } + void setParameters(IntervalParameters parameters) { m_parameters = parameters; } void setElement(int i, double f); void forceRecompute(){ m_needCompute = true;} void reset(); @@ -37,11 +37,11 @@ private: int m_numberOfElements; double m_intervalBuffer[k_maxNumberOfElements]; bool m_needCompute; - intervalParameters m_parameters; + IntervalParameters m_parameters; }; -typedef void (Interval::intervalParameters::*SetterPointer)(double); -typedef double (Interval::intervalParameters::*GetterPointer)() const; +typedef void (Interval::IntervalParameters::*SetterPointer)(double); +typedef double (Interval::IntervalParameters::*GetterPointer)() const; } diff --git a/apps/shared/interval_parameter_controller.cpp b/apps/shared/interval_parameter_controller.cpp index dc34e34d3..2404f4604 100644 --- a/apps/shared/interval_parameter_controller.cpp +++ b/apps/shared/interval_parameter_controller.cpp @@ -2,7 +2,10 @@ namespace Shared { -static Interval::intervalParameters s_tempIntevalParameters; +Interval::IntervalParameters * IntervalParameterController::SharedTempIntervalParameters() { + static Interval::IntervalParameters sTempIntervalParameters; + return &sTempIntervalParameters; +} IntervalParameterController::IntervalParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate) : FloatParameterController(parentResponder), @@ -18,9 +21,9 @@ IntervalParameterController::IntervalParameterController(Responder * parentRespo } } -void IntervalParameterController::setInterval(Interval * interval) { +void IntervalParameterController::setInterval(Interval * interval) { m_interval = interval; - s_tempIntevalParameters = *(*interval).parameters(); + *SharedTempIntervalParameters() = *(interval->parameters()); } const char * IntervalParameterController::title() { @@ -49,8 +52,8 @@ void IntervalParameterController::willDisplayCellForIndex(HighlightCell * cell, } double IntervalParameterController::parameterAtIndex(int index) { - GetterPointer getters[k_totalNumberOfCell] = {&Shared::Interval::intervalParameters::start, &Shared::Interval::intervalParameters::end, &Shared::Interval::intervalParameters::step}; - return (s_tempIntevalParameters.*getters[index])(); + GetterPointer getters[k_totalNumberOfCell] = {&Shared::Interval::IntervalParameters::start, &Shared::Interval::IntervalParameters::end, &Shared::Interval::IntervalParameters::step}; + return (SharedTempIntervalParameters()->*getters[index])(); } bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double f) { @@ -58,18 +61,18 @@ bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } - double start = parameterIndex == 0 ? f : s_tempIntevalParameters.start(); - double end = parameterIndex == 1 ? f : s_tempIntevalParameters.end(); + double start = parameterIndex == 0 ? f : SharedTempIntervalParameters()->start(); + double end = parameterIndex == 1 ? f : SharedTempIntervalParameters()->end(); if (start > end) { if (parameterIndex == 1) { Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } double g = f+1.0; - s_tempIntevalParameters.setEnd(g); + SharedTempIntervalParameters()->setEnd(g); } - SetterPointer setters[k_totalNumberOfCell] = {&Shared::Interval::intervalParameters::setStart, &Shared::Interval::intervalParameters::setEnd, &Shared::Interval::intervalParameters::setStep}; - (s_tempIntevalParameters.*setters[parameterIndex])(f); + SetterPointer setters[k_totalNumberOfCell] = {&Shared::Interval::IntervalParameters::setStart, &Shared::Interval::IntervalParameters::setEnd, &Shared::Interval::IntervalParameters::setStep}; + (SharedTempIntervalParameters()->*setters[parameterIndex])(f); return true; } @@ -92,7 +95,7 @@ int IntervalParameterController::reusableParameterCellCount(int type) { } void IntervalParameterController::buttonAction() { - m_interval->setParameters(s_tempIntevalParameters); + m_interval->setParameters(*SharedTempIntervalParameters()); m_interval->forceRecompute(); StackViewController * stack = stackController(); stack->pop(); diff --git a/apps/shared/interval_parameter_controller.h b/apps/shared/interval_parameter_controller.h index 05d511c9a..21c689a3a 100644 --- a/apps/shared/interval_parameter_controller.h +++ b/apps/shared/interval_parameter_controller.h @@ -24,6 +24,7 @@ protected: Interval * m_interval; bool handleEvent(Ion::Events::Event event) override; private: + static Interval::IntervalParameters * SharedTempIntervalParameters(); HighlightCell * reusableParameterCell(int index, int type) override; int reusableParameterCellCount(int type) override; double parameterAtIndex(int index) override; diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index b5881b21a..ecfb92b16 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -131,5 +131,4 @@ void RangeParameterController::buttonAction() { stack->pop(); } - } diff --git a/apps/shared/range_parameter_controller.h b/apps/shared/range_parameter_controller.h index 8c5a1ae95..a2006f284 100644 --- a/apps/shared/range_parameter_controller.h +++ b/apps/shared/range_parameter_controller.h @@ -36,6 +36,7 @@ private: int reusableParameterCellCount(int type) override; float parameterAtIndex(int index) override; bool setParameterAtIndex(int parameterIndex, float f) override; + void buttonAction() override; constexpr static int k_numberOfEditableTextCell = 2; constexpr static int k_numberOfConvertibleTextCell = 2; constexpr static int k_numberOfTextCell = k_numberOfEditableTextCell+k_numberOfConvertibleTextCell; @@ -44,7 +45,6 @@ private: MessageTableCellWithEditableText m_xRangeCells[k_numberOfEditableTextCell]; MessageTableCellWithConvertibleEditableText m_yRangeCells[k_numberOfConvertibleTextCell]; MessageTableCellWithSwitch m_yAutoCell; - void buttonAction() override; }; } From 5c75cc55d3c36e39062ff7177c2f16f32b92b78d Mon Sep 17 00:00:00 2001 From: Hugo Saint-Vignes Date: Mon, 27 Jul 2020 15:35:35 +0200 Subject: [PATCH 23/28] [apps/shared] Apply changes on confirm with GoTo functions Change-Id: I6ebec412b4b6612710476274a8665375d21f9ef8 --- .../graph/preimage_parameter_controller.cpp | 24 ++++++--------- .../graph/preimage_parameter_controller.h | 9 ++++-- .../regression/go_to_parameter_controller.cpp | 4 +-- apps/regression/go_to_parameter_controller.h | 4 +-- .../function_go_to_parameter_controller.cpp | 11 +------ .../function_go_to_parameter_controller.h | 9 ++++-- apps/shared/go_to_parameter_controller.cpp | 29 ++++++++++++------- apps/shared/go_to_parameter_controller.h | 16 ++++++++-- 8 files changed, 58 insertions(+), 48 deletions(-) diff --git a/apps/graph/graph/preimage_parameter_controller.cpp b/apps/graph/graph/preimage_parameter_controller.cpp index 1c1e519da..cc96183b2 100644 --- a/apps/graph/graph/preimage_parameter_controller.cpp +++ b/apps/graph/graph/preimage_parameter_controller.cpp @@ -21,10 +21,6 @@ PreimageParameterController::PreimageParameterController( { } -const char * PreimageParameterController::title() { - return I18n::translate(I18n::Message::Preimage); -} - void PreimageParameterController::viewWillAppear() { setParameterName(I18n::Message::Y); m_preimageGraphController->setImage(m_cursor->y()); @@ -32,19 +28,17 @@ void PreimageParameterController::viewWillAppear() { } void PreimageParameterController::buttonAction() { - m_preimageGraphController->setRecord(m_record); - StackViewController * stack = static_cast(parentResponder()); - stack->pop(); - stack->pop(); - stack->pop(); - stack->push(m_preimageGraphController); + if (confirmParameterAtIndex(0, m_tempParameter)) { + m_preimageGraphController->setRecord(m_record); + StackViewController * stack = static_cast(parentResponder()); + stack->pop(); + stack->pop(); + stack->pop(); + stack->push(m_preimageGraphController); + } } -double PreimageParameterController::parameterAtIndex(int index) { - assert(index == 0); - return m_preimageGraphController->image(); -} -bool PreimageParameterController::setParameterAtIndex(int parameterIndex, double f) { +bool PreimageParameterController::confirmParameterAtIndex(int parameterIndex, double f) { assert(parameterIndex == 0); m_preimageGraphController->setImage(f); return true; diff --git a/apps/graph/graph/preimage_parameter_controller.h b/apps/graph/graph/preimage_parameter_controller.h index dbe683004..1b8d1a963 100644 --- a/apps/graph/graph/preimage_parameter_controller.h +++ b/apps/graph/graph/preimage_parameter_controller.h @@ -15,13 +15,16 @@ public: Shared::CurveViewCursor * cursor, PreimageGraphController * preimageGraphController ); - const char * title() override; + const char * title() override { return I18n::translate(I18n::Message::Preimage); } void setRecord(Ion::Storage::Record record) { m_record = record; } void viewWillAppear() override; private: void buttonAction() override; - double parameterAtIndex(int index) override; - bool setParameterAtIndex(int parameterIndex, double f) override; + double extractParameterAtIndex(int index) override { + assert(index == 0); + return m_preimageGraphController->image(); + } + bool confirmParameterAtIndex(int parameterIndex, double f) override; Ion::Storage::Record m_record; PreimageGraphController * m_preimageGraphController; }; diff --git a/apps/regression/go_to_parameter_controller.cpp b/apps/regression/go_to_parameter_controller.cpp index d313f8e63..461f98bfa 100644 --- a/apps/regression/go_to_parameter_controller.cpp +++ b/apps/regression/go_to_parameter_controller.cpp @@ -30,7 +30,7 @@ const char * GoToParameterController::title() { return I18n::translate(I18n::Message::YPrediction); } -double GoToParameterController::parameterAtIndex(int index) { +double GoToParameterController::extractParameterAtIndex(int index) { assert(index == 0); if (m_xPrediction) { return m_cursor->x(); @@ -38,7 +38,7 @@ double GoToParameterController::parameterAtIndex(int index) { return m_cursor->y(); } -bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) { +bool GoToParameterController::confirmParameterAtIndex(int parameterIndex, double f) { assert(parameterIndex == 0); int series = m_graphController->selectedSeriesIndex(); Poincare::Context * globContext = AppsContainer::sharedAppsContainer()->globalContext(); diff --git a/apps/regression/go_to_parameter_controller.h b/apps/regression/go_to_parameter_controller.h index c5d27f6c7..3fa6d6aab 100644 --- a/apps/regression/go_to_parameter_controller.h +++ b/apps/regression/go_to_parameter_controller.h @@ -15,8 +15,8 @@ public: void setXPrediction(bool xPrediction); const char * title() override; private: - double parameterAtIndex(int index) override; - bool setParameterAtIndex(int parameterIndex, double f) override; + double extractParameterAtIndex(int index) override; + bool confirmParameterAtIndex(int parameterIndex, double f) override; Store * m_store; bool m_xPrediction; GraphController * m_graphController; diff --git a/apps/shared/function_go_to_parameter_controller.cpp b/apps/shared/function_go_to_parameter_controller.cpp index 3382815b1..c5b21cb43 100644 --- a/apps/shared/function_go_to_parameter_controller.cpp +++ b/apps/shared/function_go_to_parameter_controller.cpp @@ -11,16 +11,7 @@ FunctionGoToParameterController::FunctionGoToParameterController(Responder * par { } -const char * FunctionGoToParameterController::title() { - return I18n::translate(I18n::Message::Goto); -} - -double FunctionGoToParameterController::parameterAtIndex(int index) { - assert(index == 0); - return m_cursor->t(); -} - -bool FunctionGoToParameterController::setParameterAtIndex(int parameterIndex, double f) { +bool FunctionGoToParameterController::confirmParameterAtIndex(int parameterIndex, double f) { assert(parameterIndex == 0); FunctionApp * myApp = FunctionApp::app(); ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); diff --git a/apps/shared/function_go_to_parameter_controller.h b/apps/shared/function_go_to_parameter_controller.h index 5af912a31..a5680105f 100644 --- a/apps/shared/function_go_to_parameter_controller.h +++ b/apps/shared/function_go_to_parameter_controller.h @@ -9,13 +9,16 @@ namespace Shared { class FunctionGoToParameterController : public GoToParameterController { public: FunctionGoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor); - const char * title() override; + const char * title() override { return I18n::translate(I18n::Message::Goto); } void setRecord(Ion::Storage::Record record); protected: - bool setParameterAtIndex(int parameterIndex, double f) override; + bool confirmParameterAtIndex(int parameterIndex, double f) override; Ion::Storage::Record m_record; private: - double parameterAtIndex(int index) override; + double extractParameterAtIndex(int index) override { + assert(index == 0); + return m_cursor->t(); + } }; } diff --git a/apps/shared/go_to_parameter_controller.cpp b/apps/shared/go_to_parameter_controller.cpp index d72ab64d9..5151af985 100644 --- a/apps/shared/go_to_parameter_controller.cpp +++ b/apps/shared/go_to_parameter_controller.cpp @@ -11,19 +11,11 @@ GoToParameterController::GoToParameterController(Responder * parentResponder, In { } -int GoToParameterController::numberOfRows() const { - return 2; -} - HighlightCell * GoToParameterController::reusableParameterCell(int index, int type) { assert(index == 0); return &m_parameterCell; } -int GoToParameterController::reusableParameterCellCount(int type) { - return 1; -} - bool GoToParameterController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Left) { stackController()->pop(); @@ -32,10 +24,25 @@ bool GoToParameterController::handleEvent(Ion::Events::Event event) { return false; } +void GoToParameterController::viewWillAppear() { + // Initialize m_tempParameter to the extracted value. + setParameterAtIndex(0, extractParameterAtIndex(0)); + FloatParameterController::viewWillAppear(); +} + +bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) { + assert(parameterIndex == 0); + m_tempParameter = f; + return true; +} + void GoToParameterController::buttonAction() { - StackViewController * stack = (StackViewController *)parentResponder(); - stack->pop(); - stack->pop(); + // Update parameter value to m_tempParameter, and proceed if value is valid + if (confirmParameterAtIndex(0, m_tempParameter)) { + StackViewController * stack = (StackViewController *)parentResponder(); + stack->pop(); + stack->pop(); + } } } diff --git a/apps/shared/go_to_parameter_controller.h b/apps/shared/go_to_parameter_controller.h index 31516b923..24b39c5ea 100644 --- a/apps/shared/go_to_parameter_controller.h +++ b/apps/shared/go_to_parameter_controller.h @@ -11,16 +11,28 @@ namespace Shared { class GoToParameterController : public FloatParameterController { public: GoToParameterController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, InteractiveCurveViewRange * graphRange, CurveViewCursor * cursor); - int numberOfRows() const override; + int numberOfRows() const override { return 2; } bool handleEvent(Ion::Events::Event event) override; protected: void setParameterName(I18n::Message message) { m_parameterCell.setMessage(message); } + void viewWillAppear() override; + // extractParameterAtIndex extracts the current value of the parameter + virtual double extractParameterAtIndex(int index) = 0; + // confirmParameterAtIndex updates the current value of the parameter + virtual bool confirmParameterAtIndex(int parameterIndex, double f) = 0; + // parameterAtIndex and setParameterAtIndex manipulate m_tempParameter only + double parameterAtIndex(int index) override { + assert(index == 0); + return m_tempParameter; + } + bool setParameterAtIndex(int parameterIndex, double f) override; CurveViewCursor * m_cursor; InteractiveCurveViewRange * m_graphRange; + double m_tempParameter; private: void buttonAction() override; HighlightCell * reusableParameterCell(int index, int type) override; - int reusableParameterCellCount(int type) override; + int reusableParameterCellCount(int type) override { return 1; } MessageTableCellWithEditableText m_parameterCell; }; From f3628f368f9c28d149a88ae740c74b8f952f7344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 28 Jul 2020 17:07:22 +0200 Subject: [PATCH 24/28] [poincare/expression] Return undef if simplification interrupted Without this change, we would get weird "reduced" expression, such as multiplication(undef, _s), but we do not always check sSimplificationHasBeenInterrupted afterwards. --- poincare/src/expression.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 756ddd69a..f9b066832 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -817,7 +817,11 @@ Expression Expression::angleUnitToRadian(Preferences::AngleUnit angleUnit) { Expression Expression::reduce(ExpressionNode::ReductionContext reductionContext) { sSimplificationHasBeenInterrupted = false; - return deepReduce(reductionContext); + Expression result = deepReduce(reductionContext); + if (sSimplificationHasBeenInterrupted) { + return replaceWithUndefinedInPlace(); + } + return result; } Expression Expression::deepReduce(ExpressionNode::ReductionContext reductionContext) { From b8850989639260f841c771e3afaee7d7e8c5de46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 28 Jul 2020 17:09:11 +0200 Subject: [PATCH 25/28] [apps/calculation] Fix additionalInformationType If an expression hasUnits and is then reduced, it might not have units anymore for instance if it was replaced with undefined). Scenario: Enter "[5000000000000000]^20 _s" in the calculation app --- apps/calculation/calculation.cpp | 35 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/apps/calculation/calculation.cpp b/apps/calculation/calculation.cpp index 92d615b5f..975ed02f3 100644 --- a/apps/calculation/calculation.cpp +++ b/apps/calculation/calculation.cpp @@ -254,25 +254,32 @@ Calculation::AdditionalInformationType Calculation::additionalInformationType(Co } if (o.hasUnit()) { Expression unit; - PoincareHelpers::Reduce(&o, App::app()->localContext(), ExpressionNode::ReductionTarget::User,ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, ExpressionNode::UnitConversion::None); + PoincareHelpers::Reduce(&o, + App::app()->localContext(), + ExpressionNode::ReductionTarget::User, + ExpressionNode::SymbolicComputation::ReplaceAllSymbolsWithDefinitionsOrUndefined, + ExpressionNode::UnitConversion::None); o = o.removeUnit(&unit); - if (Unit::IsSI(unit)) { - if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) { - /* All these units will provide misc. classic representatives in - * addition to the SI unit in additional information. */ - return AdditionalInformationType::Unit; - } - if (Unit::IsSITime(unit)) { - /* If the number of seconds is above 60s, we can write it in the form - * of an addition: 23_min + 12_s for instance. */ - double value = Shared::PoincareHelpers::ApproximateToScalar(o, App::app()->localContext()); - if (value > Unit::SecondsPerMinute) { + // There might be no unit in the end, if the reduction was interrupted. + if (!unit.isUninitialized()) { + if (Unit::IsSI(unit)) { + if (Unit::IsSISpeed(unit) || Unit::IsSIVolume(unit) || Unit::IsSIEnergy(unit)) { + /* All these units will provide misc. classic representatives in + * addition to the SI unit in additional information. */ return AdditionalInformationType::Unit; } + if (Unit::IsSITime(unit)) { + /* If the number of seconds is above 60s, we can write it in the form + * of an addition: 23_min + 12_s for instance. */ + double value = Shared::PoincareHelpers::ApproximateToScalar(o, App::app()->localContext()); + if (value > Unit::SecondsPerMinute) { + return AdditionalInformationType::Unit; + } + } + return AdditionalInformationType::None; } - return AdditionalInformationType::None; + return AdditionalInformationType::Unit; } - return AdditionalInformationType::Unit; } if (o.isBasedIntegerCappedBy(k_maximalIntegerWithAdditionalInformation)) { return AdditionalInformationType::Integer; From edafa0e15555bdd024660e78e36756651bd85438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 28 Jul 2020 17:10:15 +0200 Subject: [PATCH 26/28] [poincare/multiplication] Assert no child is undef in removeUnit --- poincare/src/multiplication.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/poincare/src/multiplication.cpp b/poincare/src/multiplication.cpp index af665c7c7..a0cc74a7a 100644 --- a/poincare/src/multiplication.cpp +++ b/poincare/src/multiplication.cpp @@ -259,8 +259,10 @@ Expression Multiplication::removeUnit(Expression * unit) { Multiplication unitMult = Multiplication::Builder(); int resultChildrenCount = 0; for (int i = 0; i < numberOfChildren(); i++) { + Expression childI = childAtIndex(i); + assert(!childI.isUndefined()); Expression currentUnit; - Expression childI = childAtIndex(i).removeUnit(¤tUnit); + childI = childI.removeUnit(¤tUnit); if (childI.isUndefined()) { /* If the child was a unit convert, it replaced itself with an undefined * during the removeUnit. */ From 4f30089d47573062c9845f148277e338eb8c0739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Guid=C3=A9e?= Date: Thu, 6 Aug 2020 15:23:08 +0200 Subject: [PATCH 27/28] Revert "Merge pull request #393 from RedGl0w/MenuFix" This reverts commit a9d75c6c7a1730ca91e5aa9743b7b9022ce54cd5, reversing changes made to ebc9384131006163e225c910f4bc601f5fe036af. --- apps/home/controller.cpp | 14 ++------------ escher/include/escher/selectable_table_view.h | 2 +- escher/src/selectable_table_view.cpp | 18 +++++++++--------- 3 files changed, 12 insertions(+), 22 deletions(-) diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 9ba0ee2c2..2faa2e488 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -110,17 +110,6 @@ bool Controller::handleEvent(Ion::Events::Event event) { return true; } - if((numberOfIcons() % k_numberOfColumns) - && event == Ion::Events::Down - && selectionDataSource()->selectedRow() == numberOfRows() - 2 - && (numberOfIcons() % k_numberOfColumns) <= selectionDataSource()->selectedColumn()){ - return m_view.selectableTableView()->selectCellAtLocation(numberOfIcons() % k_numberOfColumns - 1, numberOfRows()-1); - } - - if(m_view.selectableTableView()->handleEvent(event, false)){ - return true; - } - if (event == Ion::Events::Home || event == Ion::Events::Back) { return m_view.selectableTableView()->selectCellAtLocation(0,0); } @@ -137,8 +126,9 @@ bool Controller::handleEvent(Ion::Events::Event event) { void Controller::didBecomeFirstResponder() { if (selectionDataSource()->selectedRow() == -1) { - m_view.selectableTableView()->selectCellAtLocation(0, 0, false); + selectionDataSource()->selectCellAtLocation(0, 0); } + Container::activeApp()->setFirstResponder(m_view.selectableTableView()); } void Controller::viewWillAppear() { diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index 23994cdfa..6e4fb7ac0 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -25,7 +25,7 @@ public: void selectRow(int j); void selectColumn(int i); void reloadData(bool setFirstResponder = true); - bool handleEvent(Ion::Events::Event event, bool setFirstResponder = true); + bool handleEvent(Ion::Events::Event event) override; void didEnterResponderChain(Responder * previousFirstResponder) override; void willExitResponderChain(Responder * nextFirstResponder) override; void deselectTable(bool withinTemporarySelection = false); diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index 0b92f7502..27f4bd395 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -132,30 +132,30 @@ HighlightCell * SelectableTableView::selectedCell() { return cellAtLocation(selectedColumn(), selectedRow()); } -bool SelectableTableView::handleEvent(Ion::Events::Event event, bool setFirstResponder) { +bool SelectableTableView::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Down) { - return selectCellAtLocation(selectedColumn(), selectedRow()+1, setFirstResponder); + return selectCellAtLocation(selectedColumn(), selectedRow()+1); } if ((event == Ion::Events::ShiftDown || event == Ion::Events::AlphaDown) && selectedRow() < dataSource()->numberOfRows()-1) { - return selectCellAtLocation(selectedColumn(), dataSource()->numberOfRows()-1, setFirstResponder); + return selectCellAtLocation(selectedColumn(), dataSource()->numberOfRows()-1); } if (event == Ion::Events::Up) { - return selectCellAtLocation(selectedColumn(), selectedRow()-1, setFirstResponder); + return selectCellAtLocation(selectedColumn(), selectedRow()-1); } if ((event == Ion::Events::ShiftUp || event == Ion::Events::AlphaUp) && selectedRow() > 0) { - return selectCellAtLocation(selectedColumn(), 0, setFirstResponder); + return selectCellAtLocation(selectedColumn(), 0); } if (event == Ion::Events::Left) { - return selectCellAtLocation(selectedColumn()-1, selectedRow(), setFirstResponder); + return selectCellAtLocation(selectedColumn()-1, selectedRow()); } if ((event == Ion::Events::ShiftLeft || event == Ion::Events::AlphaLeft) && selectedColumn() > 0) { - return selectCellAtLocation(0, selectedRow(), setFirstResponder); + return selectCellAtLocation(0, selectedRow()); } if (event == Ion::Events::Right) { - return selectCellAtLocation(selectedColumn()+1, selectedRow(), setFirstResponder); + return selectCellAtLocation(selectedColumn()+1, selectedRow()); } if ((event == Ion::Events::ShiftRight || event == Ion::Events::AlphaRight) && selectedColumn() < dataSource()->numberOfColumns()-1) { - return selectCellAtLocation(dataSource()->numberOfColumns()-1, selectedRow(), setFirstResponder); + return selectCellAtLocation(dataSource()->numberOfColumns()-1, selectedRow()); } if (event == Ion::Events::Copy || event == Ion::Events::Cut) { HighlightCell * cell = selectedCell(); From cf5cd35bc96523fccc060514224ff38445a5dd2c Mon Sep 17 00:00:00 2001 From: Charlotte THOMAS Date: Mon, 17 Aug 2020 21:52:39 +0200 Subject: [PATCH 28/28] [Change] Constants based on the CODATA 2018 (#398) --- apps/shared.universal.i18n | 58 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/apps/shared.universal.i18n b/apps/shared.universal.i18n index c2226b9d0..7775218d0 100644 --- a/apps/shared.universal.i18n +++ b/apps/shared.universal.i18n @@ -336,28 +336,28 @@ PHilaireLeRoux = "@0Babass2" SpeedOfLight = "2.99792458·10^8_m_s^-1" YearLight = "9.461·10^15_m" Boltzmann = "1.380649·10^-23_J_K^-1" -StefanBoltzmann = "5.670374·10^-8_W_m^-2_K^-4" -VacuumImpedance = "376.730313461_Ω" +StefanBoltzmann = "5.670374419·10^-8_W_m^-2_K^-4" +VacuumImpedance = "376.730313668_Ω" WaterTriplePoint = "273.16_K" AtmosphericPressure = "101325_Pa" -AtomicMassUnit = "1.660539040·10^-27_kg" -Wien = "2.8977729·10^-3_K_m" -BohrRadius = "5.2917721067·10^-11_m" -BohrMagneton = "9.274009994·10^-24_A_m^2" -NuclearMagneton = "5.050783699·10^-27_A_m^2" -MuonMass = "1.883531594·10^-28_kg" +AtomicMassUnit = "1.66053906660·10^-27_kg" +Wien = "2.897771955·10^-3_K_m" +BohrRadius = "5.29177210903·10^-11_m" +BohrMagneton = "9.2740100783·10^-24_A_m^2" +NuclearMagneton = "5.0507837461·10^-27_A_m^2" +MuonMass = "1.883531627·10^-28_kg" Avogadro = "6.02214076·10^23_mol^-1" -Gas = "8.31446261815324_J_mol^-1_K^-1" -Coulomb = "8.9875517887·10^9_N_m^2_C^-2" +Gas = "8.314462618_J_mol^-1_K^-1" +Coulomb = "8.9875517923·10^9_N_m^2_C^-2" Vacuum_permittivity = "8.8541878128·10^-12_F_m^-1" -Vacuum_permeability = "4π·10^-7_H_m^-1" +Vacuum_permeability = "1.25663706212·10^-6_H_m^-1" Planck = "6.62607015·10^-34_J_s" -ElectronMass = "9.109383·10^-31_kg" -ProtonMass = "1.672649·10^-27_kg" -NeutronMass = "1.67493·10^-27_kg" -ElementalCharge = "1.60217662·10^-19_C" +ElectronMass = "9.1093837015·10^-31_kg" +ProtonMass = "1.67262192369·10^-27_kg" +NeutronMass = "1.67492749804·10^-27_kg" +ElementalCharge = "1.602176634·10^-19_C" GAcceleration = "9.80665_m_s^-2" -GConstant = "6.674·10^-11_m^3_kg^-1_s^-2" +GConstant = "6.67430·10^-11_m^3_kg^-1_s^-2" SpeedOfSound0 = "343.4_m_s^-1" SpeedOfSoundWater = "1480_m_s^-1" SpeedOfSoundSteel = "5600_m_s^-1" @@ -370,7 +370,7 @@ EarthRadius = "6378140_m" MoonRadius = "3474600_m" EarthMoonDistance = "384400000_m" EarthSunDistance = "149597870000_m" -FaradayConstant = "96484_C_mol^-1" +FaradayConstant = "96485.33212_C_mol^-1" EscapeVelocityOfEarth = "11186_m_s^-1" EscapeVelocityOfMoon = "2380_m_s^-1" EscapeVelocityOfSun = "42100_m_s^-1" @@ -409,11 +409,11 @@ Pka14Value = "2.1" Pka15Value = "1.9" Pka16Value = "0" Pka = "pKa" -PlanckReduce = "1.504571800·10^-34_J_s" -PlanckMass = "2.176470·10^-8_kg" -PlanckLength = "1.616229·10^-35_m" -PlanckTime = "5.39116·10^-44_s" -PlanckTemperature = "1.416808·10^32_K" +PlanckReduce = "1.054571817·10^-34_J_s" +PlanckMass = "2.176434·10^-8_kg" +PlanckLength = "1.616255·10^-35_m" +PlanckTime = "5.391247·10^-44_s" +PlanckTemperature = "1.416784·10^32_K" PlanckCharge = "1.875·10^-18_C" PlanckForce = "1.210·10^44_N" PlanckEnergy = "1.956·10^9_J" @@ -425,12 +425,12 @@ PlanckTension = "1.0432·10^27_V" PlanckCurrent = "3.479·10^25_A" PlanckPressure = "4.635·10^113_Pa" PlanckImpedance = "29.986_Ω" -TauonMass = "3.16747·10^-27_kg" +TauonMass = "3.16754·10^-27_kg" WBosonMass = "1.4334·10^-25_kg" ZBosonMass = "1.62556·10^-25_kg" -FineStructure = "7.2973525664·10^-3" -RydbergConstant = "1.0973731568508·10^7_m^-1" -HartreeConstant = "4.359744650·10^-18_J" -MagneticFluxQuantum = "2.067833831·10^-15_Wb" -ConductanceQuantum = "7.7480917310·10^-5_S" -CirculationQuantum = "3.6369475486·10^-4_m^2_s^-1" \ No newline at end of file +FineStructure = "7.2973525693·10^-3" +RydbergConstant = "10973731.568160_m^-1" +HartreeConstant = "4.3597447222071·10^-18_J" +MagneticFluxQuantum = "2.067833848·10^-15_Wb" +ConductanceQuantum = "7.748091729·10^-5_S" +CirculationQuantum = "3.6369475516·10^-4_m^2_s^-1" \ No newline at end of file