From 3b25398e6e7a320b87e7293d4a2d530a403cd134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 17 Jun 2019 14:14:43 -0400 Subject: [PATCH 001/111] [shared] ScrollableExactApproximateExpressionsView: reloadScroll when displayed layouts have changed --- apps/shared/scrollable_exact_approximate_expressions_view.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/shared/scrollable_exact_approximate_expressions_view.cpp b/apps/shared/scrollable_exact_approximate_expressions_view.cpp index d878def8b..9c96d377e 100644 --- a/apps/shared/scrollable_exact_approximate_expressions_view.cpp +++ b/apps/shared/scrollable_exact_approximate_expressions_view.cpp @@ -124,6 +124,7 @@ void ScrollableExactApproximateExpressionsView::setLayouts(Poincare::Layout righ if (updateRightLayout || updateLeftLayout) { m_contentCell.reloadTextColor(); m_contentCell.layoutSubviews(); + reloadScroll(); } } From 0b8fddf576c1e0fa648b8cab4ba73385d12b09f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 17 Jun 2019 14:36:35 -0400 Subject: [PATCH 002/111] [solver] Reinitialize selected subcell when changing displayed layouts --- .../shared/scrollable_exact_approximate_expressions_cell.cpp | 5 +++++ apps/shared/scrollable_exact_approximate_expressions_cell.h | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/shared/scrollable_exact_approximate_expressions_cell.cpp b/apps/shared/scrollable_exact_approximate_expressions_cell.cpp index cfb76a462..cb88f06b1 100644 --- a/apps/shared/scrollable_exact_approximate_expressions_cell.cpp +++ b/apps/shared/scrollable_exact_approximate_expressions_cell.cpp @@ -10,6 +10,11 @@ ScrollableExactApproximateExpressionsCell::ScrollableExactApproximateExpressions { } +void ScrollableExactApproximateExpressionsCell::setLayouts(Poincare::Layout approximateLayout, Poincare::Layout exactLayout) { + m_view.setLayouts(approximateLayout, exactLayout); + m_view.setSelectedSubviewPosition(ScrollableExactApproximateExpressionsView::SubviewPosition::Left); +} + void ScrollableExactApproximateExpressionsCell::setHighlighted(bool highlight) { m_view.evenOddCell()->setHighlighted(highlight); reloadScroll(); diff --git a/apps/shared/scrollable_exact_approximate_expressions_cell.h b/apps/shared/scrollable_exact_approximate_expressions_cell.h index fd3da4ace..39c232b16 100644 --- a/apps/shared/scrollable_exact_approximate_expressions_cell.h +++ b/apps/shared/scrollable_exact_approximate_expressions_cell.h @@ -9,9 +9,7 @@ namespace Shared { class ScrollableExactApproximateExpressionsCell : public ::EvenOddCell, public Responder { public: ScrollableExactApproximateExpressionsCell(Responder * parentResponder = nullptr); - void setLayouts(Poincare::Layout approximateLayout, Poincare::Layout exactLayout) { - return m_view.setLayouts(approximateLayout, exactLayout); - } + void setLayouts(Poincare::Layout approximateLayout, Poincare::Layout exactLayout); void setEqualMessage(I18n::Message equalSignMessage) { return m_view.setEqualMessage(equalSignMessage); } From 02225098500cfa3efa6d842aa70c5a3aa78421db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 17 Jun 2019 15:32:13 -0400 Subject: [PATCH 003/111] [regression] GraphController: add missing banner view reload --- apps/regression/graph_controller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index 16c3581dc..dc6fad3c9 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -180,6 +180,7 @@ void GraphController::reloadBannerView() { for (int i = 2; i < m_bannerView.numberOfsubTexts(); i++) { m_bannerView.subTextAtIndex(i)->setText(""); } + m_bannerView.reload(); return; } char coefficientName = 'a'; From cd688ab9cfa4392758c92506915d715b50f38374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 18 Jun 2019 08:50:57 -0400 Subject: [PATCH 004/111] [apps] Force packing classes of objects contained in the Storage If these classes are padded, we lose space in the Storage and the Storage::checksum is computed on uninitialized values (corresponding to the padding memory spaces) --- apps/sequence/sequence.h | 6 ++++-- apps/shared/cartesian_function.h | 5 ++++- apps/shared/function.h | 7 ++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index e931da391..2e72fa897 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -70,7 +70,9 @@ private: constexpr static double k_maxNumberOfTermsInSum = 100000.0; /* SequenceRecordDataBuffer is the layout of the data buffer of Record - * representing a Sequence. */ + * representing a Sequence. See comment on + * Shared::Function::FunctionRecordDataBuffer about packing. */ +#pragma pack(push,1) class SequenceRecordDataBuffer : public FunctionRecordDataBuffer { public: SequenceRecordDataBuffer(KDColor color) : @@ -91,13 +93,13 @@ private: assert(conditionIndex >= 0 && conditionIndex < 2); m_initialConditionSizes[conditionIndex] = size; } - private: static_assert((1 << 8*sizeof(uint16_t)) > Ion::Storage::k_storageSize, "Potential overflows of Sequence initial condition sizes"); Type m_type; uint8_t m_initialRank; uint16_t m_initialConditionSizes[2]; }; +#pragma pack(pop) class SequenceModel : public Shared::ExpressionModel { public: diff --git a/apps/shared/cartesian_function.h b/apps/shared/cartesian_function.h index 899a4d1c6..76decc8d4 100644 --- a/apps/shared/cartesian_function.h +++ b/apps/shared/cartesian_function.h @@ -32,7 +32,9 @@ public: Poincare::Expression::Coordinate2D nextIntersectionFrom(double start, double step, double max, Poincare::Context * context, Poincare::Expression expression) const; private: /* CartesianFunctionRecordDataBuffer is the layout of the data buffer of Record - * representing a CartesianFunction. */ + * representing a CartesianFunction. See comment on + * Shared::Function::FunctionRecordDataBuffer about packing. */ +#pragma pack(push,1) class CartesianFunctionRecordDataBuffer : public FunctionRecordDataBuffer { public: CartesianFunctionRecordDataBuffer(KDColor color) : @@ -47,6 +49,7 @@ private: * the expression of the function, directly copied from the pool. */ //char m_expression[0]; }; +#pragma pack(pop) class Model : public ExpressionModel { public: void * expressionAddress(const Ion::Storage::Record * record) const override; diff --git a/apps/shared/function.h b/apps/shared/function.h index a957dc45d..753f3dc28 100644 --- a/apps/shared/function.h +++ b/apps/shared/function.h @@ -41,7 +41,11 @@ public: virtual double sumBetweenBounds(double start, double end, Poincare::Context * context) const = 0; protected: /* FunctionRecordDataBuffer is the layout of the data buffer of Record - * representing a Function. */ + * representing a Function. We want to avoid padding which would: + * - increase the size of the storage file + * - introduce junk memory zone which are then crc-ed in Storage::checksum + * creating dependency on uninitialized values. */ +#pragma pack(push,1) class FunctionRecordDataBuffer { public: FunctionRecordDataBuffer(KDColor color) : m_color(color), m_active(true) {} @@ -59,6 +63,7 @@ protected: KDColor m_color; bool m_active; }; +#pragma pack(pop) private: template T templatedApproximateAtAbscissa(T x, Poincare::Context * context, CodePoint unknownSymbol) const; FunctionRecordDataBuffer * recordData() const; From fb80cd3271461e41378a06c9f2cdef519c07313a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 18 Jun 2019 14:36:20 -0400 Subject: [PATCH 005/111] [apps] Object contained in the Storage might be unaligned. Make sure to use emscripten unaligned type to avoid producing an alignment error on emscripten platform. --- apps/sequence/sequence.h | 12 +++++++++++- apps/shared/function.h | 25 ++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/apps/sequence/sequence.h b/apps/sequence/sequence.h index 2e72fa897..2e62d4b8f 100644 --- a/apps/sequence/sequence.h +++ b/apps/sequence/sequence.h @@ -5,6 +5,10 @@ #include "sequence_context.h" #include +#if __EMSCRIPTEN__ +#include +#endif + namespace Sequence { /* WARNING: after calling setType, setInitialRank, setContent, setFirstInitialConditionContent @@ -70,7 +74,7 @@ private: constexpr static double k_maxNumberOfTermsInSum = 100000.0; /* SequenceRecordDataBuffer is the layout of the data buffer of Record - * representing a Sequence. See comment on + * representing a Sequence. See comment in * Shared::Function::FunctionRecordDataBuffer about packing. */ #pragma pack(push,1) class SequenceRecordDataBuffer : public FunctionRecordDataBuffer { @@ -97,7 +101,13 @@ private: static_assert((1 << 8*sizeof(uint16_t)) > Ion::Storage::k_storageSize, "Potential overflows of Sequence initial condition sizes"); Type m_type; uint8_t m_initialRank; +#if __EMSCRIPTEN__ + // See comment about emscripten alignement in Shared::Function::FunctionRecordDataBuffer + static_assert(sizeof(emscripten_align1_short) == sizeof(uint16_t), "emscripten_align1_short should have the same size as uint16_t"); + emscripten_align1_short m_initialConditionSizes[2]; +#else uint16_t m_initialConditionSizes[2]; +#endif }; #pragma pack(pop) diff --git a/apps/shared/function.h b/apps/shared/function.h index 753f3dc28..19c16b218 100644 --- a/apps/shared/function.h +++ b/apps/shared/function.h @@ -5,6 +5,10 @@ #include #include "expression_model_handle.h" +#if __EMSCRIPTEN__ +#include +#endif + namespace Shared { class Function : public ExpressionModelHandle { @@ -50,17 +54,24 @@ protected: public: FunctionRecordDataBuffer(KDColor color) : m_color(color), m_active(true) {} KDColor color() const { - /* Record::value() is a pointer to an address inside - * Ion::Storage::sharedStorage(), and it might be unaligned. In the method - * recordData(), we cast Record::value() to the type FunctionRecordDataBuffer. - * We must thus do some convolutions to read KDColor, which is a uint16_t - * and might produce an alignment error on the emscripten platform. */ - return KDColor::RGB16(Ion::StorageHelper::unalignedShort(reinterpret_cast(const_cast(&m_color)))); + return KDColor::RGB16(m_color); } bool isActive() const { return m_active; } void setActive(bool active) { m_active = active; } private: - KDColor m_color; +#if __EMSCRIPTEN__ + /* Record::value() is a pointer to an address inside + * Ion::Storage::sharedStorage(), and it might be unaligned. However, for + * emscripten memory representation, loads and stores must be aligned; + * performing a normal load or store on an unaligned address can fail + * silently. We thus use 'emscripten_align1_short' type, the unaligned + * version of uint16_t type to avoid producing an alignment error on the + * emscripten platform. */ + static_assert(sizeof(emscripten_align1_short) == sizeof(uint16_t), "emscripten_align1_short should have the same size as uint16_t"); + emscripten_align1_short m_color; +#else + uint16_t m_color; +#endif bool m_active; }; #pragma pack(pop) From 1043426c4064bdbf3ef65a3c7b15e27d4fbbf3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 11:34:33 +0200 Subject: [PATCH 006/111] [ion/utf8] next/previousGlyphPosition methods and tests --- ion/include/ion/unicode/utf8_decoder.h | 2 ++ ion/src/shared/unicode/utf8_decoder.cpp | 24 +++++++++++++++++++++++ ion/test/utf8_decoder.cpp | 26 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/ion/include/ion/unicode/utf8_decoder.h b/ion/include/ion/unicode/utf8_decoder.h index 432b5c072..ca7efe5e2 100644 --- a/ion/include/ion/unicode/utf8_decoder.h +++ b/ion/include/ion/unicode/utf8_decoder.h @@ -38,6 +38,8 @@ public: } CodePoint nextCodePoint(); CodePoint previousCodePoint(); + const char * nextGlyphPosition(); + const char * previousGlyphPosition(); const char * stringPosition() const { return m_stringPosition; } static size_t CharSizeOfCodePoint(CodePoint c); static size_t CodePointToChars(CodePoint c, char * buffer, size_t bufferSize); diff --git a/ion/src/shared/unicode/utf8_decoder.cpp b/ion/src/shared/unicode/utf8_decoder.cpp index af0d59d46..ea02ba7b3 100644 --- a/ion/src/shared/unicode/utf8_decoder.cpp +++ b/ion/src/shared/unicode/utf8_decoder.cpp @@ -63,6 +63,30 @@ CodePoint UTF8Decoder::previousCodePoint() { return CodePoint(result); } +const char * UTF8Decoder::nextGlyphPosition() { + assert(*m_stringPosition != 0 && (m_stringPosition == m_string || *(m_stringPosition - 1) != 0)); + CodePoint followingCodePoint = nextCodePoint(); + const char * resultGlyphPosition = m_stringPosition; + followingCodePoint = nextCodePoint(); + while (followingCodePoint != UCodePointNull && followingCodePoint.isCombining()) { + resultGlyphPosition = m_stringPosition; + followingCodePoint = nextCodePoint(); + } + m_stringPosition = resultGlyphPosition; + return resultGlyphPosition; +} + +const char * UTF8Decoder::previousGlyphPosition() { + assert(m_stringPosition > m_string); + CodePoint previousCP = previousCodePoint(); + const char * resultGlyphPosition = m_stringPosition; + while (m_stringPosition > m_string && previousCP.isCombining()) { + previousCP = previousCodePoint(); + resultGlyphPosition = m_stringPosition; + } + return resultGlyphPosition; +} + size_t UTF8Decoder::CharSizeOfCodePoint(CodePoint c) { if (c <= 0x7F) { return 1; diff --git a/ion/test/utf8_decoder.cpp b/ion/test/utf8_decoder.cpp index 26248502a..5eb482509 100644 --- a/ion/test/utf8_decoder.cpp +++ b/ion/test/utf8_decoder.cpp @@ -1,5 +1,6 @@ #include #include +#include void assert_decodes_to(const char * string, CodePoint c) { UTF8Decoder d(string); @@ -12,6 +13,18 @@ void assert_previous_code_point_is_to(const char * string, const char * stringPo quiz_assert(d.previousCodePoint() == c); } +void assert_code_point_at_next_glyph_position_is(const char * string, CodePoint c) { + UTF8Decoder d(string); + d.nextGlyphPosition(); + quiz_assert(d.nextCodePoint() == c); +} + +void assert_code_point_at_previous_glyph_position_is(const char * string, const char * stringPosition, CodePoint c) { + UTF8Decoder d(string, stringPosition); + d.previousGlyphPosition(); + quiz_assert(d.nextCodePoint() == c); +} + QUIZ_CASE(ion_utf8_decode_forward) { assert_decodes_to("\x20", 0x20); assert_decodes_to("\xC2\xA2", 0xA2); @@ -25,3 +38,16 @@ QUIZ_CASE(ion_utf8_decode_backwards) { assert_previous_code_point_is_to(a, a+4, *(a+3)); assert_previous_code_point_is_to(a, a+6, *(a+5)); } + +QUIZ_CASE(ion_utf8_decoder_next_glyph) { + const char * string = u8"a\u0065\u0301i"; + assert_code_point_at_next_glyph_position_is(string, 'e'); + assert_code_point_at_next_glyph_position_is(string+1, 'i'); +} + +QUIZ_CASE(ion_utf8_decoder_previous_glyph) { + const char * string = u8"a\u0065\u0301i"; + const char * iPosition = UTF8Helper::CodePointSearch(string, 'i'); + assert_code_point_at_previous_glyph_position_is(string, iPosition, 'e'); + assert_code_point_at_previous_glyph_position_is(string,string+1, 'a'); +} From 67eea0802fced1e6a464e69c2bc3033e9d1bb40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 11:57:01 +0200 Subject: [PATCH 007/111] [escher/text_area] Fix cursor navigation on combining code points --- escher/src/text_area.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index e1c73ea97..a8be58529 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -104,15 +104,13 @@ bool TextArea::handleEvent(Ion::Events::Event event) { return false; } UTF8Decoder decoder(text(), cursorLocation()); - decoder.previousCodePoint(); - return setCursorLocation(decoder.stringPosition()); + return setCursorLocation(decoder.previousGlyphPosition()); } else if (event == Ion::Events::Right) { if (UTF8Helper::CodePointIs(cursorLocation(), UCodePointNull)) { return false; } UTF8Decoder decoder(cursorLocation()); - decoder.nextCodePoint(); - return setCursorLocation(decoder.stringPosition()); + return setCursorLocation(decoder.nextGlyphPosition()); } else if (event == Ion::Events::Up) { contentView()->moveCursorGeo(0, -1); } else if (event == Ion::Events::Down) { From 5f549b514e17e6de54b806e56564afbb0881929a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 14:08:32 +0200 Subject: [PATCH 008/111] [escher] Fix backspace on utf8 combining code point --- apps/code/editor_controller.cpp | 2 +- escher/include/escher/text_area.h | 4 ++-- escher/include/escher/text_field.h | 2 +- escher/include/escher/text_input.h | 4 ++-- escher/src/text_area.cpp | 10 +++++----- escher/src/text_field.cpp | 8 ++++---- escher/src/text_input.cpp | 4 ++-- ion/include/ion/unicode/utf8_helper.h | 2 +- ion/src/shared/unicode/utf8_helper.cpp | 16 ++++++++-------- 9 files changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index 00b4f562a..de2dd410e 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -84,7 +84,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: numberOfSpaces = numberOfSpaces / UTF8Decoder::CharSizeOfCodePoint(' '); if (cursorIsPrecededOnTheLineBySpacesOnly && numberOfSpaces >= k_indentationSpacesNumber) { for (int i = 0; i < k_indentationSpacesNumber; i++) { - textArea->removeCodePoint(); + textArea->removePreviousGlyph(); } return true; } diff --git a/escher/include/escher/text_area.h b/escher/include/escher/text_area.h index 5ae50a583..5c0a7e973 100644 --- a/escher/include/escher/text_area.h +++ b/escher/include/escher/text_area.h @@ -77,7 +77,7 @@ protected: void insertText(const char * s, int textLength, char * location); void insertSpacesAtLocation(int numberOfSpaces, char * location); - CodePoint removeCodePoint(char * * position); + CodePoint removePreviousGlyph(char * * position); size_t removeRemainingLine(const char * position, int direction); char operator[](size_t index) { assert(index < m_bufferSize); @@ -114,7 +114,7 @@ protected: const Text * getText() const { return &m_text; } bool insertTextAtLocation(const char * text, const char * location) override; void moveCursorGeo(int deltaX, int deltaY); - bool removeCodePoint() override; + bool removePreviousGlyph() override; bool removeEndOfLine() override; bool removeStartOfLine(); protected: diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index c2725a3df..f1e7d1392 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -55,7 +55,7 @@ protected: * the maximum buffer capacity) and false is returned. */ bool insertTextAtLocation(const char * text, const char * location) override; // TODO KDSize minimalSizeForOptimalDisplay() const override; - bool removeCodePoint() override; + bool removePreviousGlyph() override; bool removeEndOfLine() override; void willModifyTextBuffer(); void didModifyTextBuffer(); diff --git a/escher/include/escher/text_input.h b/escher/include/escher/text_input.h index 80de41a50..59c576132 100644 --- a/escher/include/escher/text_input.h +++ b/escher/include/escher/text_input.h @@ -11,7 +11,7 @@ public: TextInput(Responder * parentResponder, View * contentView) : ScrollableView(parentResponder, contentView, this) {} void setFont(const KDFont * font) { contentView()->setFont(font); } const char * text() const { return nonEditableContentView()->text(); } - bool removeCodePoint(); + bool removePreviousGlyph(); const char * cursorLocation() const { return nonEditableContentView()->cursorLocation(); } bool setCursorLocation(const char * location); virtual void scrollToCursor(); @@ -30,7 +30,7 @@ protected: void setCursorLocation(const char * cursorLocation); virtual const char * text() const = 0; virtual bool insertTextAtLocation(const char * text, const char * location) = 0; - virtual bool removeCodePoint() = 0; + virtual bool removePreviousGlyph() = 0; virtual bool removeEndOfLine() = 0; KDRect cursorRect(); protected: diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index a8be58529..34254fb70 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -120,7 +120,7 @@ bool TextArea::handleEvent(Ion::Events::Event event) { } else if (event == Ion::Events::ShiftRight) { contentView()->moveCursorGeo(INT_MAX/2, 0); } else if (event == Ion::Events::Backspace) { - return removeCodePoint(); + return removePreviousGlyph(); } else if (event.hasText()) { return handleEventWithText(event.text()); } else if (event == Ion::Events::EXE) { @@ -219,12 +219,12 @@ void TextArea::Text::insertSpacesAtLocation(int numberOfSpaces, char * location) } } -CodePoint TextArea::Text::removeCodePoint(char * * position) { +CodePoint TextArea::Text::removePreviousGlyph(char * * position) { assert(m_buffer != nullptr); assert(m_buffer <= *position && *position < m_buffer + m_bufferSize); CodePoint removedCodePoint = 0; - int removedSize = UTF8Helper::RemovePreviousCodePoint(m_buffer, *position, &removedCodePoint); + int removedSize = UTF8Helper::RemovePreviousGlyph(m_buffer, *position, &removedCodePoint); assert(removedSize > 0); // Set the new cursor position @@ -405,14 +405,14 @@ bool TextArea::TextArea::ContentView::insertTextAtLocation(const char * text, co return true; } -bool TextArea::TextArea::ContentView::removeCodePoint() { +bool TextArea::TextArea::ContentView::removePreviousGlyph() { if (cursorLocation() <= text()) { assert(cursorLocation() == text()); return false; } bool lineBreak = false; char * cursorLoc = const_cast(cursorLocation()); - lineBreak = m_text.removeCodePoint(&cursorLoc) == '\n'; + lineBreak = m_text.removePreviousGlyph(&cursorLoc) == '\n'; setCursorLocation(cursorLoc); // Update the cursor layoutSubviews(); // Reposition the cursor reloadRectFromPosition(cursorLocation(), lineBreak); diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 91fcaece3..79fb719d6 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -144,7 +144,7 @@ KDSize TextField::ContentView::minimalSizeForOptimalDisplay() const { return stringSize; } -bool TextField::ContentView::removeCodePoint() { +bool TextField::ContentView::removePreviousGlyph() { assert(m_isEditing); if (m_horizontalAlignment > 0.0f) { @@ -152,9 +152,9 @@ bool TextField::ContentView::removeCodePoint() { * will not clean the first char. */ reloadRectFromPosition(m_draftTextBuffer); } - // Remove the code point if possible + // Remove the glyph if possible CodePoint removedCodePoint = 0; - int removedSize = UTF8Helper::RemovePreviousCodePoint(m_draftTextBuffer, const_cast(cursorLocation()), &removedCodePoint); + int removedSize = UTF8Helper::RemovePreviousGlyph(m_draftTextBuffer, const_cast(cursorLocation()), &removedCodePoint); if (removedSize == 0) { assert(cursorLocation() == m_draftTextBuffer); return false; @@ -325,7 +325,7 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { return true; } if (event == Ion::Events::Backspace && isEditing()) { - return removeCodePoint(); + return removePreviousGlyph(); } if (event == Ion::Events::Back && isEditing()) { setEditing(false, m_hasTwoBuffers); diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index 952dd79d5..46fd78484 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -50,8 +50,8 @@ KDRect TextInput::ContentView::dirtyRectFromPosition(const char * position, bool /* TextInput */ -bool TextInput::removeCodePoint() { - contentView()->removeCodePoint(); +bool TextInput::removePreviousGlyph() { + contentView()->removePreviousGlyph(); scrollToCursor(); return true; } diff --git a/ion/include/ion/unicode/utf8_helper.h b/ion/include/ion/unicode/utf8_helper.h index f24220a27..fb4938b11 100644 --- a/ion/include/ion/unicode/utf8_helper.h +++ b/ion/include/ion/unicode/utf8_helper.h @@ -72,7 +72,7 @@ bool CodePointIsUpperCaseLetter(CodePoint c); bool CodePointIsNumber(CodePoint c); // Shift the buffer and return the number of bytes removed. -int RemovePreviousCodePoint(const char * text, char * location, CodePoint * c); +int RemovePreviousGlyph(const char * text, char * location, CodePoint * c); /* Return the pointer to the (non combining) code point whose glyph is displayed * at the given position, and vice-versa */ diff --git a/ion/src/shared/unicode/utf8_helper.cpp b/ion/src/shared/unicode/utf8_helper.cpp index 2b4391f7d..944163d81 100644 --- a/ion/src/shared/unicode/utf8_helper.cpp +++ b/ion/src/shared/unicode/utf8_helper.cpp @@ -266,30 +266,30 @@ bool CodePointIsNumber(CodePoint c) { return c >= '0' && c <= '9'; } -int RemovePreviousCodePoint(const char * text, char * location, CodePoint * c) { +int RemovePreviousGlyph(const char * text, char * location, CodePoint * c) { assert(c != nullptr); if (location <= text) { assert(location == text); return 0; } - // Find the previous code point + // Find the previous glyph UTF8Decoder decoder(text, location); - *c = decoder.previousCodePoint(); + const char * previousGlyphPos = decoder.previousGlyphPosition(); + *c = decoder.nextCodePoint(); // Shift the buffer - int codePointSize = UTF8Decoder::CharSizeOfCodePoint(*c); - char * iterator = location - codePointSize; + int shiftedSize = location - previousGlyphPos; + char * iterator = const_cast(previousGlyphPos); assert(iterator >= text); do { - *iterator = *(iterator + codePointSize); + *iterator = *(iterator + shiftedSize); iterator++; } while (*(iterator - 1) != 0); // Stop shifting after writing a null terminating char. - return codePointSize; + return shiftedSize; } - const char * CodePointAtGlyphOffset(const char * buffer, int position) { assert(buffer != nullptr); if (position < 0) { From b696668422f7669a42f6f217d443d43e2d8f44be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 14:23:59 +0200 Subject: [PATCH 009/111] [escher/text_field] Fix cursor navigation on combining code points --- escher/src/text_field.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 79fb719d6..649e803a7 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -436,8 +436,7 @@ bool TextField::privateHandleMoveEvent(Ion::Events::Event event) { if (event == Ion::Events::Left && isEditing() && cursorLocation() > m_contentView.draftTextBuffer()) { assert(isEditing()); UTF8Decoder decoder(m_contentView.draftTextBuffer(), cursorLocation()); - decoder.previousCodePoint(); - return setCursorLocation(decoder.stringPosition()); + return setCursorLocation(decoder.previousGlyphPosition()); } if (event == Ion::Events::ShiftLeft && isEditing()) { assert(isEditing()); @@ -446,8 +445,7 @@ bool TextField::privateHandleMoveEvent(Ion::Events::Event event) { if (event == Ion::Events::Right && isEditing() && cursorLocation() < m_contentView.draftTextBuffer() + draftTextLength()) { assert(isEditing()); UTF8Decoder decoder(cursorLocation()); - decoder.nextCodePoint(); - return setCursorLocation(decoder.stringPosition()); + return setCursorLocation(decoder.nextGlyphPosition()); } if (event == Ion::Events::ShiftRight && isEditing()) { assert(isEditing()); From 5a8596acd71fea2b2039a4df12a9f7fbc2f09365 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 14:26:43 +0200 Subject: [PATCH 010/111] [ion/utf8_helper] Put default parameter in RemovePreviousGlyph --- escher/src/text_field.cpp | 5 ++--- ion/include/ion/unicode/utf8_helper.h | 2 +- ion/src/shared/unicode/utf8_helper.cpp | 5 +++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 649e803a7..122727cee 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -149,12 +149,11 @@ bool TextField::ContentView::removePreviousGlyph() { if (m_horizontalAlignment > 0.0f) { /* Reload the view. If we do it later, the text beins supposedly shorter, we - * will not clean the first char. */ + * will not clean the first char. */ reloadRectFromPosition(m_draftTextBuffer); } // Remove the glyph if possible - CodePoint removedCodePoint = 0; - int removedSize = UTF8Helper::RemovePreviousGlyph(m_draftTextBuffer, const_cast(cursorLocation()), &removedCodePoint); + int removedSize = UTF8Helper::RemovePreviousGlyph(m_draftTextBuffer, const_cast(cursorLocation())); if (removedSize == 0) { assert(cursorLocation() == m_draftTextBuffer); return false; diff --git a/ion/include/ion/unicode/utf8_helper.h b/ion/include/ion/unicode/utf8_helper.h index fb4938b11..94994b086 100644 --- a/ion/include/ion/unicode/utf8_helper.h +++ b/ion/include/ion/unicode/utf8_helper.h @@ -72,7 +72,7 @@ bool CodePointIsUpperCaseLetter(CodePoint c); bool CodePointIsNumber(CodePoint c); // Shift the buffer and return the number of bytes removed. -int RemovePreviousGlyph(const char * text, char * location, CodePoint * c); +int RemovePreviousGlyph(const char * text, char * location, CodePoint * c = nullptr); /* Return the pointer to the (non combining) code point whose glyph is displayed * at the given position, and vice-versa */ diff --git a/ion/src/shared/unicode/utf8_helper.cpp b/ion/src/shared/unicode/utf8_helper.cpp index 944163d81..d0ed6f001 100644 --- a/ion/src/shared/unicode/utf8_helper.cpp +++ b/ion/src/shared/unicode/utf8_helper.cpp @@ -267,7 +267,6 @@ bool CodePointIsNumber(CodePoint c) { } int RemovePreviousGlyph(const char * text, char * location, CodePoint * c) { - assert(c != nullptr); if (location <= text) { assert(location == text); return 0; @@ -276,7 +275,9 @@ int RemovePreviousGlyph(const char * text, char * location, CodePoint * c) { // Find the previous glyph UTF8Decoder decoder(text, location); const char * previousGlyphPos = decoder.previousGlyphPosition(); - *c = decoder.nextCodePoint(); + if (c != nullptr) { + *c = decoder.nextCodePoint(); + } // Shift the buffer int shiftedSize = location - previousGlyphPos; From cc8403e020108ffd0db9cda6d35b6a800dbcdc8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 14:42:22 +0200 Subject: [PATCH 011/111] [escher/text_input] Factorize and clean handleEvent Right and Left --- escher/include/escher/text_input.h | 4 +++- escher/src/text_area.cpp | 13 ++----------- escher/src/text_field.cpp | 26 ++++++++++++-------------- escher/src/text_input.cpp | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/escher/include/escher/text_input.h b/escher/include/escher/text_input.h index 59c576132..633fcd790 100644 --- a/escher/include/escher/text_input.h +++ b/escher/include/escher/text_input.h @@ -50,7 +50,7 @@ protected: virtual const char * editedText() const = 0; virtual size_t editedTextLength() const = 0; }; -protected: + /* If the text to be appended is too long to be added without overflowing the * buffer, nothing is done (not even adding few letters from the text to reach * the maximum buffer capacity) and false is returned. */ @@ -60,6 +60,8 @@ protected: return const_cast(nonEditableContentView()); } virtual const ContentView * nonEditableContentView() const = 0; + bool moveCursorLeft(); + bool moveCursorRight(); private: virtual void willSetCursorLocation(const char * * location) {} virtual bool privateRemoveEndOfLine(); diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index 34254fb70..2aac54475 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -99,18 +99,9 @@ bool TextArea::handleEvent(Ion::Events::Event event) { } else if (handleBoxEvent(app(), event)) { return true; } else if (event == Ion::Events::Left) { - if (cursorLocation() <= text()) { - assert(cursorLocation() == text()); - return false; - } - UTF8Decoder decoder(text(), cursorLocation()); - return setCursorLocation(decoder.previousGlyphPosition()); + return TextInput::moveCursorLeft(); } else if (event == Ion::Events::Right) { - if (UTF8Helper::CodePointIs(cursorLocation(), UCodePointNull)) { - return false; - } - UTF8Decoder decoder(cursorLocation()); - return setCursorLocation(decoder.nextGlyphPosition()); + return TextInput::moveCursorRight(); } else if (event == Ion::Events::Up) { contentView()->moveCursorGeo(0, -1); } else if (event == Ion::Events::Down) { diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 122727cee..8d23fcc54 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -432,23 +432,21 @@ void TextField::scrollToCursor() { } bool TextField::privateHandleMoveEvent(Ion::Events::Event event) { - if (event == Ion::Events::Left && isEditing() && cursorLocation() > m_contentView.draftTextBuffer()) { - assert(isEditing()); - UTF8Decoder decoder(m_contentView.draftTextBuffer(), cursorLocation()); - return setCursorLocation(decoder.previousGlyphPosition()); + if (!isEditing()) { + return false; } - if (event == Ion::Events::ShiftLeft && isEditing()) { - assert(isEditing()); - return setCursorLocation(m_contentView.draftTextBuffer()); + const char * draftBuffer = m_contentView.draftTextBuffer(); + if (event == Ion::Events::Left && cursorLocation() > draftBuffer) { + return TextInput::moveCursorLeft(); } - if (event == Ion::Events::Right && isEditing() && cursorLocation() < m_contentView.draftTextBuffer() + draftTextLength()) { - assert(isEditing()); - UTF8Decoder decoder(cursorLocation()); - return setCursorLocation(decoder.nextGlyphPosition()); + if (event == Ion::Events::Right && cursorLocation() < draftBuffer + draftTextLength()) { + return TextInput::moveCursorRight(); } - if (event == Ion::Events::ShiftRight && isEditing()) { - assert(isEditing()); - return setCursorLocation(m_contentView.draftTextBuffer() + draftTextLength()); + if (event == Ion::Events::ShiftLeft) { + return setCursorLocation(draftBuffer); + } + if (event == Ion::Events::ShiftRight) { + return setCursorLocation(draftBuffer + draftTextLength()); } return false; } diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index 46fd78484..a5cb7f293 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -96,6 +96,23 @@ bool TextInput::removeEndOfLine() { return false; } +bool TextInput::moveCursorLeft() { + if (cursorLocation() <= text()) { + assert(cursorLocation() == text()); + return false; + } + UTF8Decoder decoder(text(), cursorLocation()); + return setCursorLocation(decoder.previousGlyphPosition()); +} + +bool TextInput::moveCursorRight() { + if (UTF8Helper::CodePointIs(cursorLocation(), UCodePointNull)) { + return false; + } + UTF8Decoder decoder(cursorLocation()); + return setCursorLocation(decoder.nextGlyphPosition()); +} + bool TextInput::privateRemoveEndOfLine() { return contentView()->removeEndOfLine(); } From 2463b6bb952de14d8e15461ac4caa4c4b10efb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 21 Jun 2019 16:01:30 +0200 Subject: [PATCH 012/111] [apps/code] Update icon --- apps/code/code_icon.png | Bin 2667 -> 1621 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/code/code_icon.png b/apps/code/code_icon.png index 82d478dbaa745385a20a2d171c61c86f578d0cf9..5f4d2d1623c8911a78ebe02f76099efbbbf61306 100644 GIT binary patch delta 1572 zcmV+<2HW}T6x9rnB$GV~B!30>Nkl_Mivdvh5aZ=}Ngz zO_XS&#+aCtM5CxcA_*bEg#Yv}6N54F_(Nlim=O7cBPPZeA%tj|bB4R*kX$z$X zOLyCy-F6qYot^RhriDUVx;wkWcG#Cpwlh2X>-)@m^R5|&Nn~(vuzyBX)h)C&2!c>e zhb%Ck$cmzLFvj-Nw%zG;wv9i5je~N~54ID~`tjeHTvXC~59z&yAR`mt2+Tz%{6QyF z;V~7`zmxP|MS#A0aHAG$rZ3!h%!N3*iNnh+C}_?r%X_l{j0@-BJeuXg;cy)tXhxO^ zS$yk;ap6Tq<^5rVkyc(ILRW4V&S7$JRXlDD1{(}1`vx4L8g6yG0=rXZjK!@ ziV9Is-~{EUM*_#WEX=^w+pl-x-1&ddcI^gw{e7S!Ab|n`s@xS=wqyaGd3rg4i-y5* zE=FlUP2Wli_WrmJfBk(qZR;s_YOhu+`1N&CFob{*gD*aKCEU-$$4XgYHq&#!*UJeKS4 zm$c7%Z>~l7hml_ zb(I^J|7+0#&3|-?;e8qhYt5^{D(xzN8<5aBcTUyQvjWw23)TowZPlm(s4q7&smX5Bz!rM~|OQSWX$&uM9)z z{P{t+(ZALFI>Z-!qQRzp&mH{jD2_Cq${bjtnsMMNS$}m``T@mv%a6m2P3G&iZyo}M zg6YAXXgY^!F_@YlKdLeWe^YvJS6bRL&gF3AfhA!Tgf68H7meOVUw<&;aP?2tf=L&X zxc6F9hwJL`WgN^s%Y~Io>%qGACx(j!w5XaAoD>RY6s+3g#^!g|!rHM5>~?pOU2-(F zJU2KPO@B$rnPnwpfpS{Ksv*ZnRHWd+!l%H_{!Xsuhn`0iOp&3c0+*MUoAf_fvTzVjLdQ-kKU5SA0%&<4e>8qm193dAO3q6S67q$i);Wru2%t6Jj-;Jr=j;jSp3ez4q1DAa|kxyd~Q*7YES*PD^Z zSb`Qs5w7wwh^IGzMXrw};t6?<_APmcFZ=qzi1l!_Chm*51m)6oF?3D8iV6#~E!DXQ z)8-=g!%b41II5s{-puUuEB)|B-Lvmd!hiBhEm{m11eeuA+3AC$qBp+qBgoGkgi^QF z#BhRs?^a7zK`nb$E1?wkt5BU!jIJe`3@*>3|2KDf$EIAo=^Pyjsd?4L)zyZ?3eW2h zdmEu=4#)=EAzs=>)y7KdD2|Oxy!gnxvcWjd4~0Ss<*T$CFrnulgezZaQE}2dmw%{P zrS>I0|3iXZZU|UB9#>gkUtiE}w;S@34U2R@Xxj-EXc|{cPXWivDc4I-X1@*C%M7zx zEEbbkPfyP;1qB6b3=LC!E)u)|CS3v>XrcXnu;H*4AywXB=2Sq4j1TLuOO_GMG@<~*EBO9jzrbRC(oI~%|_ z2j{t$=e%BTglJbtlGJII=Wx1<0@9o7&p9~H14*0?_#%su^Pz#+a#qXrs6xcMJ^;?Wdf!ouDSXdKv$}00RIU WK2x=upEk7s00000Dy!50Qvv`0D$NK z0Cg|`0P0`>06Lfe02gqax=}m;000JJOGiWi{{a60|De66lK=n!32;bRa{vGr5&!@f z5&>tQ(oz5b00(qQO+^Rc2ni4&8K`D>p8x;}HAzH4RA}DantxerT;&zVf9Ec-#O>|?g(XM(rFf8 zJ=lt$ zfNj@XyB6TDzz={cmWZ^A$WQ-IhymM#eZF4;_4K|LJ>a* z&@jXg0)H&a!m({E+a}_=Boc8p_HN+TTL$Rw+fF3nw$hv1Wp-w!U|CkQ8Di;lhBx1S zpJShXPBxoERS^-YBSJ*3QM_^=kH@(CuG`uF*gjIJWJ?GdV-7jZ3Q<*#{NorO9r*-R zC6!7Ni$$54NfQLYHHKL1zECJ~=nr#JI6WoAh z34f=D&-15O|3c^54o(lBBcCs@oHEmzU~Dlt)shE;AmEFWLvyND^J-NsT~%_nWsyoH z@PnW(0pIt@=L2>E=0_YWT7(BV&*O=lXm+G4UAT6ZF-KZ}_e z014R3uL9FPKy3{3SjN!cx4)eG74q=Qb7uVHD3<6SV0CetKO@EQ% z$Q#%leYidQV2MbmS?4Sf&Yd6Qqr)F#jJYn^?pn@*23frEchDfqQiiTc&V(T+K0ie| zlUp@n4F$Yd1T#Z~=~0jsk}DQHM#nBTI%P{BKq{F)f^<2VEIvxTSxovIEApI(Fg-KN z^vvw)c}R1I0!dM$-$G{To^Yg-Fqi(*<<*VCrV1PIxU*j){QuAbq%s8IaQ^zb4~dSq=xNOS+k~{P2KJI z6UXbK=lkzOYuZooDJPwH7%p6#9}d`wugGNtWHA>pnr&)#Ob`X94X5r z2c?8EIM9dd)=Q{To^BPPirwCa-O<1DT>-$&yLPf=^Tt-6<2OYN%O%qL2;wGL%B)sx zIi=I%{f~W(uJxUSVK{e;H=kry;xnx}Dp>5p;`ilUx!b)Lcf*4XO;JWol}se9)>W5RF8M#|jjeGNXprsqMrDo0O1 zcIXWr+BQT^RdF4M?wi&x@RSf_#+Mc#7GeGh#WSy!+8m)g-@C)R)ovtDhmbdSafCQeH=4nJ}mt?Bo^*!)3{C3AyGVRduOkpi-BSz+}h4 z6z9ja2&+i03L0X!_Y=S61+3V5isNrl9DWtlYhHF0n*W!OSSt`CIO}#}cMKrWP9hr~ zLfizPh!bl`NPjj@P8Er)!D{Pac{NWl=@GOz2^wN%hEY=hJBpp^Te7Wc5XK2r3l^;W zowyStvguJw`V3l}YRq0@5lntc?z3NF#k)$o?;wxceIL%c-3_Puy5>_Iu`~=%G${qA za}TlpXR#6+neQf+dd?6`9>*Jd6ZK|sdmbjf>xYQjPJgrAs;Y)T5DYuM@4xLh&ix|N z*bD5%AcEU{KX!5p-ldNSCXW*4E}=oL?1k`JZ-|XV*J8Ktz}@g5Zr44fb=Lx~g<&{R z^t^XvbY$e_WHR}BBof)xwA6BeR&N@Uxq!)x66P+T#j9wLFA<8gW5v3#lbf*;o3Pq? zN;~Rh7JukkP*nJMQFD4U-U)Z+YqJP9nIpdW>^ec*&>s=*jw0M*2 zdESL|Ci8T}bw9L*hliP-p8j1fm-|D#7l_NWUlpke8N2+cBGr0gv)Nqk=f8RRij#}1@`ETG#pX>YnjOTd=^ZER*hR&RMZ`+nFp@=Xz zI5^+P4Gj&Us%-4-Wpr$;CmM}D?AZ4Gw&QHFL^@d3q2hlPqF}->oHWJ^1-^eUm(PFP z(SOk~o5^OeEsMdy!P3C$r%s(Zg{op%7V&tT&6_uK^ytyJ>$05UK!H!UzYEigG$ zF*Z6gGdeXhD=;!TFfdm{O%DJ703~!qSSoa6VRU6WZEs|0W_bWIFflhRFgPtRIaDz= hIx{mmGBqnOGCD9YPYlVBks&7v002ovPDHLkV1h1!<-z~} From cd4260494a9098c54460ff649282ab9a4f8eb896 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 21 Jun 2019 15:07:32 +0200 Subject: [PATCH 013/111] [kandinsky/fonts/LargeFont.ttf] Change the glyphs of 0 and 3 characters --- kandinsky/fonts/LargeFont.ttf | Bin 219444 -> 219324 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/kandinsky/fonts/LargeFont.ttf b/kandinsky/fonts/LargeFont.ttf index 46b67f74d6733ff75cd16c128336bd3c8d9a4daf..0dda11f09a115a4158dae88b284eac6dd00cd8ea 100644 GIT binary patch delta 3329 zcmZYAUr@ym7a_U`Wa*Sn zm<|ujz*KB`U|O2+z!)&Au1XaXRIJ)!OYNp1mZX@FNE4cDDmC=a*Y=?gb>?&T{?70G z&N=tqQ9Y+-_x8+g3UlXrL?kGEW7?*b%U0SXAUBWort}>sV(=rE7G}iTU!J4%Lfl_Y5mFAZe z&Ny{{i3B_~Dx!DF%PK14ZbklB0wR0A?>p@?ub{++%aOJU{xG$J5rQ z0(620dzUl))b1zNUxzk$L7#s5ToE@H3SOb$m3k1oD&Wx73^4W8R`i3tYdpcVR8a6* z7l>bDfB_4lKzx7(*Qs$m7Sy;tDdtxl=*Nhd8|>ZSjoom<%|tgSe2d^MhPdSb4Szi# z<~Q|X25s<*xlMuF6u3Pq=C>BaA_w*8KtD#s{LUg~h+0EKVt!Bj4)=F>6MtwD<0Iea z0dM8KAVi6AzsJ-3F&LHL!28_4-wp~4(|nl2A5i22e(y5eUH0zM=EBs53Pv<{ulunSX}B-N}VU|B6B?a!}6S+<1(O8W(PgY5_(>19C(y zq39KzWJCm2ot=d)(Z@)9 z%rE+QyJ$$0=o|`v%YrG7&_;W-q#1G$sdQ zqOq~aLkp<0i2Fqy7!r*O0d?bwMHlCS{CMic`$U%nxw)jmi8gR}X%J|#v<7{m%LI0? zUe+s`zug}Xt{%Pc!O!=%hl|=NYR?0c+9_i128GsVq8triy}=3xS}`p898Z{L2eCBHrg1in zvuWg}(R5QVlHn0eCpVqkbaK*w6H0RCH@Rh;60mR`Rx`q7pRRMr_-V==Km~p`7o(y$KxNJ}8xiEEZE^dl`mu9;eVz&!pqTh3ZUq=+kanQukC;Cz-IQz1o0Y1?^@!;H^ z0nt3_bNQVj1Az{yKDl zrbXly5icTEM8Tp-QD-W0;X*6C@L^K)KsZv73m4!2KpQtqc3?#Gpdbo%IMIY&jENqi z(IFd%A0mFp3(gb=gM!6*Xawy2Jw;xbYobwlz6EX3{YCn_b+9m)F)ad;3>=4 zD60eUG76Q4z>adXV^H)J3sO;x4h)GNCU%&Hhj~MXTi^u^D`;3jyuyKcP`843C3P#^ zHZD%IVE}&7SL2ZbhIrM3QPCq2$U_tQMUPVSC<7ej?9on8(8Zf@WuX>V6xuV^fqCM>OjElaVAnM5xJ>4aG z#%AY2;#sCT+XfDJN%S^>xOWIlel8vicAlxv^MAj{BfA~_UmPDC(zyZF$3HqdHl&&L F{|2QpM*aW* delta 3440 zcmZYCUrRW z$4q$O!I_ZOWO(3#wmdL(V>S{0G!TmsE2hL!iS;T_v$t-~ zT~%M^YY?4CV(s2lSM7D|JLF;=5Xl+c>p8q<*NGk*dn2M}BDK4#YvOLdw?K5LkJy@8 z0#S7{?uy=-WSv%9=kt%PeKk=Y)uAbogegz`uIgE{&$>m=PKels>#F_UneRu%upZ!m zeSdY`?pY`AWJ*+Gm55&R)*tkxUrGLnL@mmDVff8q^U^PaizQc9Q#@v7%*@o3W$Dv@ z^79JT6s%djYJS4>pLi>K(W_S#tjW(?mY$jtGc(>gzaTY#wV5cerKM!0EwwK!NKAY< zIcLSjZL9K=V`oH1&xpN$epgLKhGXUS9XYv~7ybTiS@D)x7E65A=FK}_t9B&BXXb8M zl4Va=|M24FOR7sA4K|mQY%OnSD1ODm=s)c|VO|SrjJ8e>$0!WMV5#}jH~*RAzmvo) z`({vvjAz!Egm0dsAhfSEHzzvUS=g{LKR+eKYPH)_vX`W$ugzWQSX))F_J}JxD@xPT z*Ew=u-LkwWIk|9EX6lA{^OBO5CMPd^=)t(Sl=+J?7ud40p73TzKaiQRVV%P<$FgOO z$V*)zbE+$(Keh!=*u7W2MG%vB0prNGrH1ki>7 zOo{nj5{giTfS4g_{k}}hHR9K}{{wGg*aGseXM?wLy$Q#~1h4Zne>{o_F*i7HgZmL1 zC@@0v4>UpSX@i!-W=f zAR^{tYJS|t_y2^=Pnyv!=2MD&I(=oB@pdt{v%%}T9R{&K7orz5xKoB9F%uR9#QY@| zPTUpq*Q4kc^BJ+vTxb;&Auqykkx4Os^I%lW=T5%==QR9#9@xC=15a{~ja7a zs6d;TFRY;17d*jaHhRVUGY*w#!HAeIGeFLloc$^frpoKewWY=`LFe$fZgK;k@)Xq-*-K?^ASt$^r5K2a-;tV5#lBccg3 zn@^6dLUaN93u{CZ*-tztnnbOnyQ0Z)CD3i1=esOWMlIJ~?GG+BOEG^-GPbc1zv9@x*O(25!a&9!|r6==xaDWW5{ITudZqqJbZuWF>Wa890rqaq{zk$P-tTx z#zh|yuzsWyL!ytyp#nVNCeCgmwu!SPoGsyO3ArV197UICX*S3$CAXB^QgU77y2|0H?!W%dNb>9N5cp5%8F16;$`PBCi*!0k2_F>b`aY_(=Fs}31LEX zD-E|2+ggTZ^kbawUv2@1%Ux(fhv+t9+lp}%46|)g^a&@L!Tu9{py+lAZufxuifGiL z6a66eqzeH|i9SW%Qw;YML+=pqKs$otqLoZtIVk#cF=)1vA$CSYzvITJXcgD0;~?i5 znmkj87I5~ve$i(IsdY5bFg8_e_fJO#@B$lDn7qUShQrto0&f1g!!ACv8? zgdfMzjZx9(EXac!GvF1#jxlh3yMI|Lkw_;vwk}$=;uxN z`$Z4Of%Reb4@X3wcfbqQ&kupR4Ng!u*x=`e;tgyz(6nJ(G{9>NP&D8I0|nR*bc4fz z3DHJ|XiNh|8Y$99jYe`BsnJM{Mrs_P#t~{9Vb~*;@Zp%~i*2GUouV&?F~IkKndDZI zTS;yuxz&wkbYT!Qe8q;s|7oLXM>&Q?e^!f#=+B!#?l1B{qfQ6N>l_pf^@+aD-pLx# zH#$Va1EO!GA%FRZm(} From 95403c8a9165a7ab08797e1508d75f1b7c1977e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 25 Jun 2019 14:23:03 +0200 Subject: [PATCH 014/111] [python/port] Increase stack limit on emscripten, simulator... The value is quite arbitrary, we just do not want to outperfom the device but still provide more recursion depth. --- python/port/port.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/port/port.cpp b/python/port/port.cpp index ba1106936..5fb130dc0 100644 --- a/python/port/port.cpp +++ b/python/port/port.cpp @@ -105,7 +105,7 @@ void MicroPython::init(void * heapStart, void * heapEnd) { #else volatile int stackTop; mp_stack_set_top((void *)(&stackTop)); - mp_stack_set_limit(4000); + mp_stack_set_limit(8192); #endif gc_init(heapStart, heapEnd); mp_init(); From 05c479a6fcd59762e6fab619ca1d554aff0f8552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 16:43:40 +0200 Subject: [PATCH 015/111] [poincare] Better collapsing of fractions The user can now write intuitively 1/2 * 3/4 --- poincare/src/code_point_layout.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/poincare/src/code_point_layout.cpp b/poincare/src/code_point_layout.cpp index 4d08a014c..9d8a01fb6 100644 --- a/poincare/src/code_point_layout.cpp +++ b/poincare/src/code_point_layout.cpp @@ -59,6 +59,24 @@ bool CodePointLayoutNode::isCollapsable(int * numberOfOpenParenthesis, bool goin return false; } } + if (isMultiplicationCodePoint()) { + /* We want '*' to be collapsable only if the following brother is not a + * fraction, so that the user can write intuitively "1/2 * 3/4". */ + Layout thisRef = CodePointLayout(this); + Layout parent = thisRef.parent(); + if (!parent.isUninitialized()) { + int indexOfThis = parent.indexOfChild(thisRef); + Layout brother; + if (indexOfThis > 0 && goingLeft) { + brother = parent.childAtIndex(indexOfThis-1); + } else if (indexOfThis < parent.numberOfChildren() - 1 && !goingLeft) { + brother = parent.childAtIndex(indexOfThis+1); + } + if (!brother.isUninitialized() && brother.type() == LayoutNode::Type::FractionLayout) { + return false; + } + } + } return true; } From 5f20c1d0c49335cf401bca18e2bfcb3f3973958f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 25 Jun 2019 18:15:05 +0200 Subject: [PATCH 016/111] [apps] Fix portuguese typo --- apps/language_pt.universal.i18n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/language_pt.universal.i18n b/apps/language_pt.universal.i18n index 40da6052d..9545890e9 100644 --- a/apps/language_pt.universal.i18n +++ b/apps/language_pt.universal.i18n @@ -1 +1 @@ -LanguagePT = "Portugués " +LanguagePT = "Português " From e72c7d85645c5e87449bc51f6ed4cca932c8bff5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 25 Jun 2019 18:06:54 +0200 Subject: [PATCH 017/111] [escher/layout_field] Fix cursor position when inserting layout Scenario : In calculation, write 10/7, enter Go up, press OK on 10/7 -> the cursor is not on the right of the layout --- escher/src/layout_field.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/escher/src/layout_field.cpp b/escher/src/layout_field.cpp index f771c6473..b691b73b8 100644 --- a/escher/src/layout_field.cpp +++ b/escher/src/layout_field.cpp @@ -310,8 +310,9 @@ void LayoutField::insertLayoutAtCursor(Layout layoutR, Poincare::Expression corr /* Move the cursor if needed. * - * If forceCursorRightOfLayout is true, there is no need to move the cursor - * because it already points to the right of the added layout. + * If forceCursorRightOfLayout is true and the layout has been merged, there + * is no need to move the cursor because it already points to the right of the + * added layouts. * * If the layout to point to has been merged, only its children have been * inserted in the layout. We already computed where the cursor should point, @@ -342,6 +343,9 @@ void LayoutField::insertLayoutAtCursor(Layout layoutR, Poincare::Expression corr assert(!cursorMergedLayout.isUninitialized()); m_contentView.cursor()->setLayout(cursorMergedLayout); m_contentView.cursor()->setPosition(LayoutCursor::Position::Right); + } else if (!layoutWillBeMerged) { + m_contentView.cursor()->setLayout(layoutR); + m_contentView.cursor()->setPosition(LayoutCursor::Position::Right); } // Handle matrices From a0b21b9931e3d39827529d2a4a90ba138eca5265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 11:54:07 +0200 Subject: [PATCH 018/111] [poincare/tests] Unparsable layouts test --- poincare/test/layouts.cpp | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/poincare/test/layouts.cpp b/poincare/test/layouts.cpp index 37e55e170..54ef4fb83 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layouts.cpp @@ -41,6 +41,14 @@ void assert_parsed_layout_is(Layout l, Poincare::Expression r) { quiz_assert(identical); } +void assert_layout_is_not_parsed(Layout l) { + constexpr int bufferSize = 500; + char buffer[bufferSize]; + l.serializeForParsing(buffer, bufferSize); + Expression e = parse_expression(buffer, true); + quiz_assert(e.isUninitialized()); +} + QUIZ_CASE(poincare_create_all_layouts) { EmptyLayout e0 = EmptyLayout::Builder(); AbsoluteValueLayout e1 = AbsoluteValueLayout::Builder(e0); @@ -306,3 +314,94 @@ QUIZ_CASE(poincare_layouts_comparison) { quiz_assert(e11.isIdenticalTo(e12)); quiz_assert(!e11.isIdenticalTo(e13)); } + +QUIZ_CASE(poincare_unparsable_layouts) { + { + /* (1 + * --- + * 2) + * */ + Layout l = FractionLayout::Builder( + HorizontalLayout::Builder( + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')), + HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder())); + assert_layout_is_not_parsed(l); + } + + { + // ( √2) + Layout l = HorizontalLayout::Builder( + LeftParenthesisLayout::Builder(), + NthRootLayout::Builder( + HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder()))); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * ∑ (5) + * n=1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = SumLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * π (5) + * n=1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = ProductLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('n'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } + + { + /* 2)+(1 + * ∫ (5)dx + * 1 + */ + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('2'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = ProductLayout::Builder( + CodePointLayout::Builder('5'), + CodePointLayout::Builder('x'), + CodePointLayout::Builder('1'), + HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } +} From 6109903f6683b6307f111ca5835240bf794f3059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 11:43:31 +0200 Subject: [PATCH 019/111] [poincare/serialization] Use system parentheses to serialize This solves the problem : (1 --- that serialized as ((1)/(2)), which was valid 2) --- ion/include/ion/unicode/code_point.h | 5 +-- poincare/src/parsing/parser.cpp | 52 ++++++++++++++++----------- poincare/src/parsing/parser.h | 2 ++ poincare/src/parsing/token.h | 2 ++ poincare/src/parsing/tokenizer.cpp | 6 ++++ poincare/src/serialization_helper.cpp | 4 +-- 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/ion/include/ion/unicode/code_point.h b/ion/include/ion/unicode/code_point.h index c069f7e39..e8b7cb5aa 100644 --- a/ion/include/ion/unicode/code_point.h +++ b/ion/include/ion/unicode/code_point.h @@ -26,11 +26,12 @@ static constexpr CodePoint UCodePointUnknownN = 0x2; static constexpr CodePoint UCodePointTabulation = 0x9; static constexpr CodePoint UCodePointLineFeed = 0xa; -/* 0x11, 0x12, 0x13 represent DEVICE CONTROL ONE TO THREE. They are not used, so - * we can use them for another purpose */ +// 0x11 to 0x15 are not used, so we can use them for another purpose static constexpr CodePoint UCodePointEmpty = 0x11; // Used to be parsed into EmptyExpression static constexpr CodePoint UCodePointLeftSuperscript = 0x12; // Used to parse Power static constexpr CodePoint UCodePointRightSuperscript = 0x13; // Used to parse Power +static constexpr CodePoint UCodePointLeftSystemParenthesis = 0x14; // Used for serialization +static constexpr CodePoint UCodePointRightSystemParenthesis = 0x15; // Used for serialization static constexpr CodePoint UCodePointMiddleDot = 0xb7; // · static constexpr CodePoint UCodePointMultiplicationSign = 0xd7; // × diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index cda117ec0..cc9f502d3 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -43,7 +43,7 @@ bool Parser::IsSpecialIdentifierName(const char * name, size_t nameLength) { Token::CompareNonNullTerminatedName(name, nameLength, Symbol::k_ans) == 0 || Token::CompareNonNullTerminatedName(name, nameLength, Infinity::Name()) == 0 || Token::CompareNonNullTerminatedName(name, nameLength, Undefined::Name()) == 0 || - Token::CompareNonNullTerminatedName(name, nameLength, Unreal::Name()) == 0 || + Token::CompareNonNullTerminatedName(name, nameLength, Unreal::Name()) == 0 || Token::CompareNonNullTerminatedName(name, nameLength, "u_") == 0 || Token::CompareNonNullTerminatedName(name, nameLength, "v_") == 0 || Token::CompareNonNullTerminatedName(name, nameLength, "u") == 0 || @@ -62,6 +62,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) { &Parser::parseUnexpected, // Token::RightBracket &Parser::parseUnexpected, // Token::RightParenthesis &Parser::parseUnexpected, // Token::RightBrace + &Parser::parseUnexpected, // Token::RightSystemParenthesis &Parser::parseUnexpected, // Token::Comma &Parser::parsePlus, // Token::Plus &Parser::parseMinus, // Token::Minus @@ -74,6 +75,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) { &Parser::parseMatrix, // Token::LeftBracket &Parser::parseLeftParenthesis, // Token::LeftParenthesis &Parser::parseUnexpected, // Token::LeftBrace + &Parser::parseLeftSystemParenthesis, // Token::LeftSystemParenthesis &Parser::parseEmpty, // Token::Empty &Parser::parseConstant, // Token::Constant &Parser::parseNumber, // Token::Number @@ -132,6 +134,7 @@ void Parser::isThereImplicitMultiplication() { m_nextToken.is(Token::Constant) || m_nextToken.is(Token::Identifier) || m_nextToken.is(Token::LeftParenthesis) || + m_nextToken.is(Token::LeftSystemParenthesis) || m_nextToken.is(Token::LeftBracket) ); } @@ -290,20 +293,11 @@ bool Parser::parseBinaryOperator(const Expression & leftHandSide, Expression & r } void Parser::parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppingType) { - if (!leftHandSide.isUninitialized()) { - m_status = Status::Error; //FIXME - return; - } - leftHandSide = parseUntil(Token::RightParenthesis); - if (m_status != Status::Progress) { - return; - } - if (!popTokenIfType(Token::RightParenthesis)) { - m_status = Status::Error; // Right parenthesis missing. - return; - } - leftHandSide = Parenthesis::Builder(leftHandSide); - isThereImplicitMultiplication(); + defaultParseLeftParenthesis(false, leftHandSide, stoppingType); +} + +void Parser::parseLeftSystemParenthesis(Expression & leftHandSide, Token::Type stoppingType) { + defaultParseLeftParenthesis(true, leftHandSide, stoppingType); } void Parser::parseBang(Expression & leftHandSide, Token::Type stoppingType) { @@ -418,7 +412,7 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, m_status = Status::Error; // Identifier name too long. return; } - if (!popTokenIfType(Token::LeftParenthesis)) { + if (!popTokenIfType(Token::LeftParenthesis) && !popTokenIfType(Token::LeftSystemParenthesis)) { leftHandSide = Symbol::Builder(name, length); return; } @@ -434,7 +428,7 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, parameter = parameter.childAtIndex(0); if (parameter.type() == ExpressionNode::Type::Symbol && strncmp(static_cast(parameter).name(), name, length) == 0) { m_status = Status::Error; // Function and variable must have distinct names. - } else if (!popTokenIfType(Token::RightParenthesis)) { + } else if (!popTokenIfType(Token::RightParenthesis) && !popTokenIfType(Token::RightSystemParenthesis)) { m_status = Status::Error; // Right parenthesis missing. } else { leftHandSide = Function::Builder(name, length, parameter); @@ -461,18 +455,18 @@ void Parser::parseIdentifier(Expression & leftHandSide, Token::Type stoppingType } Expression Parser::parseFunctionParameters() { - if (!popTokenIfType(Token::LeftParenthesis)) { + if (!popTokenIfType(Token::LeftParenthesis) && !popTokenIfType(Token::LeftSystemParenthesis)) { m_status = Status::Error; // Left parenthesis missing. return Expression(); } - if (popTokenIfType(Token::RightParenthesis)) { + if (popTokenIfType(Token::RightParenthesis) || popTokenIfType(Token::RightSystemParenthesis) ) { return Matrix::Builder(); // The function has no parameter. } Expression commaSeparatedList = parseCommaSeparatedList(); if (m_status != Status::Progress) { return Expression(); } - if (!popTokenIfType(Token::RightParenthesis)) { + if (!popTokenIfType(Token::RightParenthesis) && !popTokenIfType(Token::RightSystemParenthesis)) { m_status = Status::Error; // Right parenthesis missing. return Expression(); } @@ -539,4 +533,22 @@ Expression Parser::parseCommaSeparatedList() { return commaSeparatedList; } +void Parser::defaultParseLeftParenthesis(bool isSystemParenthesis, Expression & leftHandSide, Token::Type stoppingType) { + if (!leftHandSide.isUninitialized()) { + m_status = Status::Error; //FIXME + return; + } + Token::Type endToken = isSystemParenthesis ? Token::Type::RightSystemParenthesis : Token::Type::RightParenthesis; + leftHandSide = parseUntil(endToken); + if (m_status != Status::Progress) { + return; + } + if (!popTokenIfType(endToken)) { + m_status = Status::Error; // Right parenthesis missing. + return; + } + leftHandSide = Parenthesis::Builder(leftHandSide); + isThereImplicitMultiplication(); +} + } diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h index fac7bf1c1..dd08a501a 100644 --- a/poincare/src/parsing/parser.h +++ b/poincare/src/parsing/parser.h @@ -52,6 +52,7 @@ private: void parseEmpty(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseMatrix(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseLeftParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); + void parseLeftSystemParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseBang(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parsePlus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseMinus(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); @@ -74,6 +75,7 @@ private: void parseSpecialIdentifier(Expression & leftHandSide); void parseSequence(Expression & leftHandSide, const char name, Token::Type leftDelimiter, Token::Type rightDelimiter); void parseCustomIdentifier(Expression & leftHandSide, const char * name, size_t length); + void defaultParseLeftParenthesis(bool isSystemParenthesis, Expression & leftHandSide, Token::Type stoppingType); // Data members Status m_status; diff --git a/poincare/src/parsing/token.h b/poincare/src/parsing/token.h index 000200cda..2401020eb 100644 --- a/poincare/src/parsing/token.h +++ b/poincare/src/parsing/token.h @@ -30,6 +30,7 @@ public: RightBracket, RightParenthesis, RightBrace, + RightSystemParenthesis, Comma, Plus, Minus, @@ -46,6 +47,7 @@ public: LeftBracket, LeftParenthesis, LeftBrace, + LeftSystemParenthesis, Empty, Constant, Number, diff --git a/poincare/src/parsing/tokenizer.cpp b/poincare/src/parsing/tokenizer.cpp index 6c5b8c762..37f8b6497 100644 --- a/poincare/src/parsing/tokenizer.cpp +++ b/poincare/src/parsing/tokenizer.cpp @@ -138,6 +138,12 @@ Token Tokenizer::popToken() { if (c == UCodePointMultiplicationSign || c == UCodePointMiddleDot) { return Token(Token::Times); } + if (c == UCodePointLeftSystemParenthesis) { + return Token(Token::LeftSystemParenthesis); + } + if (c == UCodePointRightSystemParenthesis) { + return Token(Token::RightSystemParenthesis); + } if (c == '^') { return Token(Token::Caret); } diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index 7c9ec1fb9..f32292b1a 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -39,7 +39,7 @@ static int serializeChild( // Write the child with parentheses if needed bool addParentheses = parentNode->childNeedsParenthesis(childNode); if (addParentheses) { - numberOfChar += UTF8Decoder::CodePointToChars('(', buffer+numberOfChar, bufferSize - numberOfChar); + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointLeftSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } @@ -50,7 +50,7 @@ static int serializeChild( return bufferSize-1; } if (addParentheses) { - numberOfChar += UTF8Decoder::CodePointToChars(')', buffer+numberOfChar, bufferSize - numberOfChar); + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointRightSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); } if (numberOfChar >= bufferSize-1) { assert(buffer[bufferSize - 1] == 0); From 40c5196ceee2b0bb9f97222d133167faa1fdfd25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 13:38:26 +0200 Subject: [PATCH 020/111] [test] Use strcmpWithSystemParentheses Now there can be two types of parentheses : '(' or UCodePointLeftSystemParenthesis. Because we do not want to complicate the test results, when comparing a computed serialization and a result we do not differentiate between the two types of parentheses. --- apps/calculation/test/calculation_store.cpp | 6 ++-- apps/solver/test/equation_store.cpp | 6 ++-- poincare/test/helper.cpp | 33 +++++++++++++++++---- poincare/test/helper.h | 2 ++ 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/apps/calculation/test/calculation_store.cpp b/apps/calculation/test/calculation_store.cpp index 05633b529..15d3f0588 100644 --- a/apps/calculation/test/calculation_store.cpp +++ b/apps/calculation/test/calculation_store.cpp @@ -77,10 +77,12 @@ void assertCalculationDisplay(const char * input, ::Calculation::Calculation::Di quiz_assert(lastCalculation->exactAndApproximateDisplayedOutputsAreEqual(context) == sign); } if (exactOutput) { - quiz_assert(strcmp(lastCalculation->exactOutputText(), exactOutput) == 0); + constexpr int bufferSize = 500; + char buffer[bufferSize]; + quiz_assert(strcmpWithSystemParentheses(lastCalculation->exactOutputText(), exactOutput) == 0); } if (approximateOutput) { - quiz_assert(strcmp(lastCalculation->approximateOutputText(), approximateOutput) == 0); + quiz_assert(strcmpWithSystemParentheses(lastCalculation->approximateOutputText(), approximateOutput) == 0); } store->deleteAll(); } diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index 3452d6901..b33dda50e 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -40,16 +40,16 @@ void assert_equation_system_exact_solve_to(const char * equations[], EquationSto } if (type == EquationStore::Type::LinearSystem) { for (int i = 0; i < numberOfSolutions; i++) { - quiz_assert(strcmp(equationStore.variableAtIndex(i),variables[i]) == 0); + quiz_assert(strcmpWithSystemParentheses(equationStore.variableAtIndex(i),variables[i]) == 0); } } else { - quiz_assert(strcmp(equationStore.variableAtIndex(0), variables[0]) == 0); + quiz_assert(strcmpWithSystemParentheses(equationStore.variableAtIndex(0), variables[0]) == 0); } constexpr int bufferSize = 200; char buffer[bufferSize]; for (int i = 0; i < numberOfSolutions; i++) { equationStore.exactSolutionLayoutAtIndex(i, true).serializeForParsing(buffer, bufferSize); - quiz_assert(strcmp(buffer, solutions[i]) == 0); + quiz_assert(strcmpWithSystemParentheses(buffer, solutions[i]) == 0); } equationStore.removeAll(); } diff --git a/poincare/test/helper.cpp b/poincare/test/helper.cpp index fc3436671..9cb7fc05a 100644 --- a/poincare/test/helper.cpp +++ b/poincare/test/helper.cpp @@ -41,6 +41,28 @@ bool expressions_are_equal(Poincare::Expression expected, Poincare::Expression g return identical; } +bool isLeftParenthesisCodePoint(CodePoint c) { + return (c == UCodePointLeftSystemParenthesis) || (c == '('); +} + +bool isRightParenthesisCodePoint(CodePoint c) { + return (c == UCodePointRightSystemParenthesis) || (c == ')'); +} + +int strcmpWithSystemParentheses(const char * s1, const char * s2) { + quiz_assert(UTF8Decoder::CharSizeOfCodePoint(UCodePointLeftSystemParenthesis) == 1); + quiz_assert(UTF8Decoder::CharSizeOfCodePoint(UCodePointRightSystemParenthesis) == 1); + while(*s1 != 0 + && ((*s1 == *s2) + || (isLeftParenthesisCodePoint(*s1) && isLeftParenthesisCodePoint(*s2)) + || (isRightParenthesisCodePoint(*s1) && isRightParenthesisCodePoint(*s2)))) + { + s1++; + s2++; + } + return (*(unsigned char *)s1) - (*(unsigned char *)s2); +} + Expression parse_expression(const char * expression, bool canBeUnparsable) { quiz_print(expression); Expression result = Expression::Parse(expression); @@ -98,13 +120,14 @@ void assert_parsed_expression_process_to(const char * expression, const char * r print_expression(e, 0); #endif Expression m = process(e, globalContext, target, complexFormat, angleUnit); - char buffer[500]; - m.serialize(buffer, sizeof(buffer), DecimalMode, numberOfSignifiantDigits); + constexpr int bufferSize = 500; + char buffer[bufferSize]; + m.serialize(buffer, bufferSize, DecimalMode, numberOfSignifiantDigits); #if POINCARE_TESTS_PRINT_EXPRESSIONS cout << "---- serialize to: " << buffer << " ----" << endl; cout << "----- compared to: " << result << " ----\n" << endl; #endif - quiz_assert(strcmp(buffer, result) == 0); + quiz_assert(strcmpWithSystemParentheses(buffer, result) == 0); } template @@ -190,7 +213,7 @@ void assert_parsed_expression_layout_serialize_to_self(const char * expressionLa #if POINCARE_TESTS_PRINT_EXPRESSIONS cout << "---- serialized to: " << buffer << " ----\n" << endl; #endif - quiz_assert(strcmp(expressionLayout, buffer) == 0); + quiz_assert(strcmpWithSystemParentheses(expressionLayout, buffer) == 0); } void assert_expression_layouts_as(Poincare::Expression expression, Poincare::Layout layout) { @@ -207,7 +230,7 @@ void assert_expression_layout_serialize_to(Poincare::Layout layout, const char * cout << "---- serialized to: " << buffer << " ----" << endl; cout << "----- compared to: " << serialization << " ----\n" << endl; #endif - quiz_assert(strcmp(serialization, buffer) == 0); + quiz_assert(strcmpWithSystemParentheses(serialization, buffer) == 0); } template void assert_parsed_expression_evaluates_to(char const*, char const *, Poincare::ExpressionNode::ReductionTarget, Poincare::Preferences::AngleUnit, Poincare::Preferences::ComplexFormat, int); diff --git a/poincare/test/helper.h b/poincare/test/helper.h index 091d68d74..91d728ce0 100644 --- a/poincare/test/helper.h +++ b/poincare/test/helper.h @@ -18,6 +18,8 @@ constexpr Poincare::Preferences::ComplexFormat Real = Poincare::Preferences::Com constexpr Poincare::Preferences::PrintFloatMode DecimalMode = Poincare::Preferences::PrintFloatMode::Decimal; constexpr Poincare::Preferences::PrintFloatMode ScientificMode = Poincare::Preferences::PrintFloatMode::Scientific; +int strcmpWithSystemParentheses(const char * s1, const char * s2); + bool expressions_are_equal(Poincare::Expression expected, Poincare::Expression got); Poincare::Expression parse_expression(const char * expression, bool canBeUnparsable = false); Poincare::Expression parse_and_simplify(const char * expression); From 6455891b7738371e065004c4386f288d0cee67ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 13:46:59 +0200 Subject: [PATCH 021/111] [apps/test] Silence unused variable warning --- apps/solver/test/equation_store.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index b33dda50e..ad082640c 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -14,6 +14,7 @@ namespace Solver { void addEquationWithText(EquationStore * equationStore, const char * text) { Ion::Storage::Record::ErrorStatus err = equationStore->addEmptyModel(); assert(err == Ion::Storage::Record::ErrorStatus::None); + (void) err; // Silence warning in DEBUG=0 Ion::Storage::Record record = equationStore->recordAtIndex(equationStore->numberOfModels()-1); Shared::ExpiringPointer model = equationStore->modelForRecord(record); model->setContent(text); From e64b8cabc8d090d7e6b70d50fe3e93d2d4925004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 13:47:07 +0200 Subject: [PATCH 022/111] [poincare/test] Test about 2^(3+4)! layout serialization --- poincare/test/layouts.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/poincare/test/layouts.cpp b/poincare/test/layouts.cpp index 54ef4fb83..c68a27420 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layouts.cpp @@ -157,6 +157,25 @@ QUIZ_CASE(poincare_parse_layouts) { Rational::Builder(4))); assert_parsed_layout_is(l, e); + // 2^(3+4)! + l = HorizontalLayout::Builder( + CodePointLayout::Builder('2'), + VerticalOffsetLayout::Builder( + HorizontalLayout::Builder( + CodePointLayout::Builder('3'), + CodePointLayout::Builder('+'), + CodePointLayout::Builder('4')), + VerticalOffsetLayoutNode::Position::Superscript), + CodePointLayout::Builder('!')); + e = Factorial::Builder( + Power::Builder( + Rational::Builder(2), + Addition::Builder( + Rational::Builder(3), + Rational::Builder(4)))); + assert_parsed_layout_is(l, e); + + // log_3(2) HorizontalLayout l1 = HorizontalLayout::Builder(); l1.addChildAtIndex(CodePointLayout::Builder('l'), l1.numberOfChildren(), l1.numberOfChildren(), nullptr); From 2028fca481280b0c94ac07224983bf660c5c7ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 14:08:54 +0200 Subject: [PATCH 023/111] [poincare/nth_root_layout] Fix serialization The layout (3 root3) is not parsable anymore --- .../include/poincare/serialization_helper.h | 3 +- poincare/src/nth_root_layout.cpp | 41 ++++--------------- poincare/src/serialization_helper.cpp | 20 ++++----- 3 files changed, 20 insertions(+), 44 deletions(-) diff --git a/poincare/include/poincare/serialization_helper.h b/poincare/include/poincare/serialization_helper.h index 84ff6d32c..a68f5389e 100644 --- a/poincare/include/poincare/serialization_helper.h +++ b/poincare/include/poincare/serialization_helper.h @@ -31,7 +31,8 @@ namespace SerializationHelper { Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, - bool writeFirstChild = true); + int firstChildIndex = 0, + int lastChildIndex = -1); // Write one code point in a buffer and a null-terminating char int CodePoint(char * buffer, int bufferSize, CodePoint c); diff --git a/poincare/src/nth_root_layout.cpp b/poincare/src/nth_root_layout.cpp index e0860d315..1e31536af 100644 --- a/poincare/src/nth_root_layout.cpp +++ b/poincare/src/nth_root_layout.cpp @@ -148,42 +148,17 @@ void NthRootLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) { } int NthRootLayoutNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - // Case: root(x,n) - if (m_hasIndex - && (const_cast(this))->indexLayout() - && !(const_cast(this))->indexLayout()->isEmpty()) - { + if (m_hasIndex) { + assert((const_cast(this))->indexLayout()); + if ((const_cast(this))->indexLayout()->isEmpty()) { + // Case: root(x,empty): Write "'SquareRootSymbol'('radicandLayout')" + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::s_functionHelper.name(), true, false); + } + // Case: root(x,n) return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::s_functionHelper.name()); } // Case: squareRoot(x) - if (!m_hasIndex) { - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::s_functionHelper.name()); - } - // Case: root(x,empty) - // Write "'SquareRootSymbol'('radicandLayout')". - assert((const_cast(this))->indexLayout() && (const_cast(this))->indexLayout()->isEmpty()); - if (bufferSize == 0) { - return -1; - } - buffer[bufferSize-1] = 0; - int numberOfChar = 0; - - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointSquareRoot); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; - } - - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '('); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; - } - - numberOfChar += (const_cast(this))->radicandLayout()->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits); - if (numberOfChar >= bufferSize-1) { return bufferSize-1; } - - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ')'); - buffer[numberOfChar] = 0; - return numberOfChar; + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::s_functionHelper.name()); } KDSize NthRootLayoutNode::computeSize() { diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index f32292b1a..595888df5 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -117,7 +117,8 @@ int SerializationHelper::Prefix( Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, - bool writeFirstChild) + int firstChildIndex, + int lastChildIndex) { { int result = 0; @@ -133,18 +134,17 @@ int SerializationHelper::Prefix( return bufferSize-1; } - // Add the opening parenthese - numberOfChar += UTF8Decoder::CodePointToChars('(', buffer+numberOfChar, bufferSize - numberOfChar); + // Add the opening parenthesis + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointLeftSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } int childrenCount = node->numberOfChildren(); if (childrenCount > 0) { - if (!writeFirstChild) { - assert(childrenCount > 1); - } - int firstChildIndex = writeFirstChild ? 0 : 1; + assert(childrenCount > firstChildIndex); + int lastIndex = lastChildIndex < 0 ? childrenCount - 1 : lastChildIndex; + assert(firstChildIndex <= lastIndex); // Write the first child numberOfChar += node->childAtIndex(firstChildIndex)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits); @@ -154,7 +154,7 @@ int SerializationHelper::Prefix( } // Write the remaining children, separated with commas - for (int i = firstChildIndex + 1; i < childrenCount; i++) { + for (int i = firstChildIndex + 1; i <= lastIndex; i++) { numberOfChar += UTF8Decoder::CodePointToChars(',', buffer+numberOfChar, bufferSize - numberOfChar); if (numberOfChar >= bufferSize-1) { return bufferSize-1; @@ -167,8 +167,8 @@ int SerializationHelper::Prefix( } } - // Add the closing parenthese - numberOfChar += UTF8Decoder::CodePointToChars(')', buffer+numberOfChar, bufferSize - numberOfChar); + // Add the closing parenthesis + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointRightSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } From 23c2358f19e9ad30b1df9aeb577de36e5d3ecff1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 14:18:01 +0200 Subject: [PATCH 024/111] [poincare] Clean Factorial serialization --- .../include/poincare/serialization_helper.h | 8 ++++++++ poincare/src/factorial.cpp | 17 ++--------------- poincare/src/serialization_helper.cpp | 6 +++--- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/poincare/include/poincare/serialization_helper.h b/poincare/include/poincare/serialization_helper.h index a68f5389e..ac38a895f 100644 --- a/poincare/include/poincare/serialization_helper.h +++ b/poincare/include/poincare/serialization_helper.h @@ -34,6 +34,14 @@ namespace SerializationHelper { int firstChildIndex = 0, int lastChildIndex = -1); + int SerializeChild( + const TreeNode * childNode, + const TreeNode * parentNode, + char * buffer, + int bufferSize, + Preferences::PrintFloatMode floatDisplayMode, + int numberOfDigits); + // Write one code point in a buffer and a null-terminating char int CodePoint(char * buffer, int bufferSize, CodePoint c); }; diff --git a/poincare/src/factorial.cpp b/poincare/src/factorial.cpp index c39f262cd..402b54bd8 100644 --- a/poincare/src/factorial.cpp +++ b/poincare/src/factorial.cpp @@ -67,21 +67,8 @@ Layout FactorialNode::createLayout(Preferences::PrintFloatMode floatDisplayMode, } int FactorialNode::serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const { - if (bufferSize == 0) { - return -1; - } - buffer[bufferSize-1] = 0; - int numberOfChar = 0; - if (childNeedsParenthesis(childAtIndex(0))) { - numberOfChar += SerializationHelper::CodePoint(&buffer[numberOfChar], bufferSize-numberOfChar, '('); - if (numberOfChar >= bufferSize-1) { return bufferSize-1; } - } - numberOfChar += childAtIndex(0)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits); - if (childNeedsParenthesis(childAtIndex(0))) { - numberOfChar += SerializationHelper::CodePoint(&buffer[numberOfChar], bufferSize-numberOfChar, ')'); - if (numberOfChar >= bufferSize-1) { return bufferSize-1; } - } - if (numberOfChar >= bufferSize-1) { + int numberOfChar = SerializationHelper::SerializeChild(childAtIndex(0), this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits); + if ((numberOfChar < 0) || (numberOfChar >= bufferSize-1)) { return numberOfChar; } numberOfChar += SerializationHelper::CodePoint(&buffer[numberOfChar], bufferSize-numberOfChar, '!'); diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index 595888df5..2f9b1f773 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -20,7 +20,7 @@ static bool checkBufferSize(char * buffer, int bufferSize, int * result) { return false; } -static int serializeChild( +int SerializationHelper::SerializeChild( const TreeNode * childNode, const TreeNode * parentNode, char * buffer, @@ -83,7 +83,7 @@ int SerializationHelper::Infix( assert(numberOfChildren > 0); // Write the first child, with parentheses if needed - numberOfChar+= serializeChild(node->childAtIndex(firstChildIndex), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); + numberOfChar+= SerializeChild(node->childAtIndex(firstChildIndex), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); if (numberOfChar >= bufferSize-1) { assert(buffer[bufferSize - 1] == 0); return bufferSize-1; @@ -98,7 +98,7 @@ int SerializationHelper::Infix( return bufferSize-1; } // Write the child, with parentheses if needed - numberOfChar+= serializeChild(node->childAtIndex(i), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); + numberOfChar+= SerializeChild(node->childAtIndex(i), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); if (numberOfChar >= bufferSize-1) { assert(buffer[bufferSize - 1] == 0); return bufferSize-1; From b6638bb92921f7e1b9c712f8b96047664b32aafd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 14:42:39 +0200 Subject: [PATCH 025/111] [poincare] Serialize with UCodePointLeftSystemParenthesis In fraction, integral and sequence layouts --- poincare/src/fraction_layout.cpp | 4 ++-- poincare/src/integral_layout.cpp | 4 ++-- poincare/src/sequence_layout.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poincare/src/fraction_layout.cpp b/poincare/src/fraction_layout.cpp index 589ba4fcf..6a57d5d80 100644 --- a/poincare/src/fraction_layout.cpp +++ b/poincare/src/fraction_layout.cpp @@ -142,7 +142,7 @@ int FractionLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr if (idxInParent >= 0 && idxInParent < (p->numberOfChildren() - 1) && p->type() == Type::HorizontalLayout && p->childAtIndex(idxInParent + 1)->type() == Type::VerticalOffsetLayout) { addParenthesis = true; // Add parenthesis - numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '('); + numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointLeftSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1;} } @@ -152,7 +152,7 @@ int FractionLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr if (addParenthesis) { // Add parenthesis - numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ')'); + numberOfChar+= SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1;} } diff --git a/poincare/src/integral_layout.cpp b/poincare/src/integral_layout.cpp index d156508bb..2d27d9b47 100644 --- a/poincare/src/integral_layout.cpp +++ b/poincare/src/integral_layout.cpp @@ -160,7 +160,7 @@ int IntegralLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr } // Write the opening parenthesis - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '('); + numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointLeftSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } @@ -179,7 +179,7 @@ int IntegralLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pr } // Write the closing parenthesis - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ')'); + numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis); buffer[numberOfChar] = 0; return numberOfChar; } diff --git a/poincare/src/sequence_layout.cpp b/poincare/src/sequence_layout.cpp index ba4ac205c..e3e231ca8 100644 --- a/poincare/src/sequence_layout.cpp +++ b/poincare/src/sequence_layout.cpp @@ -213,7 +213,7 @@ int SequenceLayoutNode::writeDerivedClassInBuffer(const char * operatorName, cha if (numberOfChar >= bufferSize-1) { return bufferSize-1; } // Write the opening parenthesis - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, '('); + numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointLeftSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } LayoutNode * argLayouts[] = {const_cast(this)->argumentLayout(), const_cast(this)->variableLayout(), const_cast(this)->lowerBoundLayout(), const_cast(this)->upperBoundLayout()}; @@ -228,7 +228,7 @@ int SequenceLayoutNode::writeDerivedClassInBuffer(const char * operatorName, cha } // Write the closing parenthesis - numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, ')'); + numberOfChar += SerializationHelper::CodePoint(buffer + numberOfChar, bufferSize - numberOfChar, UCodePointRightSystemParenthesis); buffer[numberOfChar] = 0; return numberOfChar; } From b98559907900861ea7758fdaeafcd63dedc1638e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 16:26:08 +0200 Subject: [PATCH 026/111] [poincare] Remove unused parameter in SerializationHelper::Prefix --- .../include/poincare/serialization_helper.h | 1 - poincare/src/nth_root_layout.cpp | 2 +- poincare/src/serialization_helper.cpp | 23 +++++++------------ 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/poincare/include/poincare/serialization_helper.h b/poincare/include/poincare/serialization_helper.h index ac38a895f..29d47aa91 100644 --- a/poincare/include/poincare/serialization_helper.h +++ b/poincare/include/poincare/serialization_helper.h @@ -31,7 +31,6 @@ namespace SerializationHelper { Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, - int firstChildIndex = 0, int lastChildIndex = -1); int SerializeChild( diff --git a/poincare/src/nth_root_layout.cpp b/poincare/src/nth_root_layout.cpp index 1e31536af..7eb8b2e04 100644 --- a/poincare/src/nth_root_layout.cpp +++ b/poincare/src/nth_root_layout.cpp @@ -152,7 +152,7 @@ int NthRootLayoutNode::serialize(char * buffer, int bufferSize, Preferences::Pri assert((const_cast(this))->indexLayout()); if ((const_cast(this))->indexLayout()->isEmpty()) { // Case: root(x,empty): Write "'SquareRootSymbol'('radicandLayout')" - return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::s_functionHelper.name(), true, false); + return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, SquareRoot::s_functionHelper.name(), 0); } // Case: root(x,n) return SerializationHelper::Prefix(this, buffer, bufferSize, floatDisplayMode, numberOfSignificantDigits, NthRoot::s_functionHelper.name()); diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index 2f9b1f773..860c3d0fa 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -117,7 +117,6 @@ int SerializationHelper::Prefix( Preferences::PrintFloatMode floatDisplayMode, int numberOfDigits, const char * operatorName, - int firstChildIndex, int lastChildIndex) { { @@ -142,22 +141,16 @@ int SerializationHelper::Prefix( int childrenCount = node->numberOfChildren(); if (childrenCount > 0) { - assert(childrenCount > firstChildIndex); int lastIndex = lastChildIndex < 0 ? childrenCount - 1 : lastChildIndex; - assert(firstChildIndex <= lastIndex); - // Write the first child - numberOfChar += node->childAtIndex(firstChildIndex)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits); - if (numberOfChar >= bufferSize-1) { - assert(buffer[bufferSize - 1] == 0); - return bufferSize-1; - } - - // Write the remaining children, separated with commas - for (int i = firstChildIndex + 1; i <= lastIndex; i++) { - numberOfChar += UTF8Decoder::CodePointToChars(',', buffer+numberOfChar, bufferSize - numberOfChar); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; + // Write the children, separated with commas + for (int i = 0; i <= lastIndex; i++) { + if (i != 0) { + // Write the comma + numberOfChar += UTF8Decoder::CodePointToChars(',', buffer+numberOfChar, bufferSize - numberOfChar); + if (numberOfChar >= bufferSize-1) { + return bufferSize-1; + } } numberOfChar += node->childAtIndex(i)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits); if (numberOfChar >= bufferSize-1) { From 4945868ec03ee14e03b692cd3e586b6402dc8342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Mon, 24 Jun 2019 17:04:30 +0200 Subject: [PATCH 027/111] [poincare] Factorize SerializationHelper::Infix and Prefix --- poincare/src/serialization_helper.cpp | 126 ++++++++++++-------------- 1 file changed, 59 insertions(+), 67 deletions(-) diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index 860c3d0fa..34f25f169 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -60,7 +60,8 @@ int SerializationHelper::SerializeChild( return numberOfChar; } -int SerializationHelper::Infix( +int InfixPrefix( + bool prefix, const TreeNode * node, char * buffer, int bufferSize, @@ -77,39 +78,77 @@ int SerializationHelper::Infix( } } - // Get some information on the node int numberOfChar = 0; - int numberOfChildren = node->numberOfChildren(); - assert(numberOfChildren > 0); - // Write the first child, with parentheses if needed - numberOfChar+= SerializeChild(node->childAtIndex(firstChildIndex), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); - if (numberOfChar >= bufferSize-1) { - assert(buffer[bufferSize - 1] == 0); - return bufferSize-1; - } - // For all remaining children: - int lastIndex = lastChildIndex < 0 ? numberOfChildren - 1 : lastChildIndex; - for (int i = firstChildIndex + 1; i < lastIndex+1; i++) { - // Write the operator - numberOfChar += strlcpy(buffer+numberOfChar, operatorName, bufferSize-numberOfChar); + if (prefix) { + // Prefix: Copy the operator name + numberOfChar = strlcpy(buffer, operatorName, bufferSize); if (numberOfChar >= bufferSize-1) { assert(buffer[bufferSize - 1] == 0); return bufferSize-1; } - // Write the child, with parentheses if needed - numberOfChar+= SerializeChild(node->childAtIndex(i), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); + // Add the opening parenthesis + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointLeftSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); + if (numberOfChar >= bufferSize-1) { + return bufferSize-1; + } + } + + int childrenCount = node->numberOfChildren(); + assert(prefix || childrenCount > 0); + + if (childrenCount > 0) { + int lastIndex = lastChildIndex < 0 ? childrenCount - 1 : lastChildIndex; + assert(firstChildIndex <= lastIndex); + + // Write the children, separated with commas or the operator + for (int i = firstChildIndex; i <= lastIndex; i++) { + if (i != firstChildIndex) { + // Write the operator or the comma + numberOfChar += prefix ? + UTF8Decoder::CodePointToChars(',', buffer+numberOfChar, bufferSize - numberOfChar) : + strlcpy(buffer+numberOfChar, operatorName, bufferSize-numberOfChar); + if (numberOfChar >= bufferSize-1) { + assert(buffer[bufferSize - 1] == 0); + return bufferSize-1; + } + } + // Write the child, with or without parentheses if needed + numberOfChar+= prefix ? + node->childAtIndex(i)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits) : + SerializationHelper::SerializeChild(node->childAtIndex(i), node, buffer + numberOfChar, bufferSize - numberOfChar, floatDisplayMode, numberOfDigits); + if (numberOfChar >= bufferSize-1) { + assert(buffer[bufferSize - 1] == 0); + return bufferSize-1; + } + } + } + + if (prefix) { + // Add the closing parenthesis + numberOfChar += UTF8Decoder::CodePointToChars(UCodePointRightSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); if (numberOfChar >= bufferSize-1) { - assert(buffer[bufferSize - 1] == 0); return bufferSize-1; } } - // Null-terminate the buffer buffer[numberOfChar] = 0; return numberOfChar; } +int SerializationHelper::Infix( + const TreeNode * node, + char * buffer, + int bufferSize, + Preferences::PrintFloatMode floatDisplayMode, + int numberOfDigits, + const char * operatorName, + int firstChildIndex, + int lastChildIndex) +{ + return InfixPrefix(false, node, buffer, bufferSize, floatDisplayMode, numberOfDigits, operatorName, firstChildIndex, lastChildIndex); +} + int SerializationHelper::Prefix( const TreeNode * node, char * buffer, @@ -119,54 +158,7 @@ int SerializationHelper::Prefix( const char * operatorName, int lastChildIndex) { - { - int result = 0; - if (checkBufferSize(buffer, bufferSize, &result)) { - return result; - } - } - - // Copy the operator name - int numberOfChar = strlcpy(buffer, operatorName, bufferSize); - if (numberOfChar >= bufferSize-1) { - assert(buffer[bufferSize - 1] == 0); - return bufferSize-1; - } - - // Add the opening parenthesis - numberOfChar += UTF8Decoder::CodePointToChars(UCodePointLeftSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; - } - - int childrenCount = node->numberOfChildren(); - if (childrenCount > 0) { - int lastIndex = lastChildIndex < 0 ? childrenCount - 1 : lastChildIndex; - - // Write the children, separated with commas - for (int i = 0; i <= lastIndex; i++) { - if (i != 0) { - // Write the comma - numberOfChar += UTF8Decoder::CodePointToChars(',', buffer+numberOfChar, bufferSize - numberOfChar); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; - } - } - numberOfChar += node->childAtIndex(i)->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfDigits); - if (numberOfChar >= bufferSize-1) { - assert(buffer[bufferSize - 1] == 0); - return bufferSize-1; - } - } - } - - // Add the closing parenthesis - numberOfChar += UTF8Decoder::CodePointToChars(UCodePointRightSystemParenthesis, buffer+numberOfChar, bufferSize - numberOfChar); - if (numberOfChar >= bufferSize-1) { - return bufferSize-1; - } - buffer[numberOfChar] = 0; - return numberOfChar; + return InfixPrefix(true, node, buffer, bufferSize, floatDisplayMode, numberOfDigits, operatorName, 0, lastChildIndex); } int SerializationHelper::CodePoint(char * buffer, int bufferSize, class CodePoint c) { From 2fdbf2ea11a957add0c47db3bd0361cf08e55c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 25 Jun 2019 10:20:50 +0200 Subject: [PATCH 028/111] [poincare] VerticalOffsetLyt serializes as ^(). UCodePointLeftSuperscript and UCodePointRightSuperscript no longer exist --- apps/solver/test/equation_store.cpp | 16 +++++----- ion/include/ion/unicode/code_point.h | 6 ++-- poincare/src/parsing/parser.cpp | 40 ++++++++++++------------ poincare/src/parsing/parser.h | 1 + poincare/src/parsing/token.h | 7 ++--- poincare/src/parsing/tokenizer.cpp | 9 ++---- poincare/src/vertical_offset_layout.cpp | 9 +++--- poincare/test/vertical_offset_layout.cpp | 6 ++-- 8 files changed, 44 insertions(+), 50 deletions(-) diff --git a/apps/solver/test/equation_store.cpp b/apps/solver/test/equation_store.cpp index ad082640c..096529c19 100644 --- a/apps/solver/test/equation_store.cpp +++ b/apps/solver/test/equation_store.cpp @@ -123,14 +123,14 @@ QUIZ_CASE(equation_solve) { const char * solutions10[] = {"1", "0"}; assert_equation_system_exact_solve_to(equations10, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions10, 2); - quiz_assert(UCodePointLeftSuperscript == '\022'); - quiz_assert(UCodePointLeftSuperscript == '\x12'); - quiz_assert(UCodePointRightSuperscript == '\023'); - quiz_assert(UCodePointRightSuperscript == '\x13'); + quiz_assert(UCodePointLeftSystemParenthesis == '\022'); + quiz_assert(UCodePointLeftSystemParenthesis == '\x12'); + quiz_assert(UCodePointRightSystemParenthesis == '\023'); + quiz_assert(UCodePointRightSystemParenthesis == '\x13'); // x^2+x+1=3×x^2+pi×x-√(5) const char * equations11[] = {"x^2+x+1=3×x^2+π×x-√(5)", 0}; - const char * solutions11[] = {"(√(π\0222\023-2·π+8·√(5)+9)-π+1)/(4)", "(-√(π\0222\023-2·π+8·√(5)+9)-π+1)/(4)", "π\0222\023-2·π+8·√(5)+9"}; + const char * solutions11[] = {"(√(π^\0222\023-2·π+8·√(5)+9)-π+1)/(4)", "(-√(π^\0222\023-2·π+8·√(5)+9)-π+1)/(4)", "π^\0222\023-2·π+8·√(5)+9"}; assert_equation_system_exact_solve_to(equations11, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions11, 3); // TODO @@ -231,18 +231,18 @@ QUIZ_CASE(equation_solve_complex_format) { Poincare::Preferences::sharedPreferences()->setComplexFormat(Poincare::Preferences::ComplexFormat::Polar); // x+𝐢 = 0 --> x = e^(-π/2×i) - const char * solutions0Polar[] = {"ℯ\x12-(π)/(2)·𝐢\x13"}; + const char * solutions0Polar[] = {"ℯ^\x12-(π)/(2)·𝐢\x13"}; assert_equation_system_exact_solve_to(equations0, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1); // x+√(-1) = 0 --> x = e^(-π/2×𝐢) assert_equation_system_exact_solve_to(equations1, EquationStore::Error::NoError, EquationStore::Type::LinearSystem, (const char **)variablesx, solutions0Polar, 1); // x^2+x+1=0 - const char * solutions2Polar[] = {"ℯ\x12-(2·π)/(3)·𝐢\x13","ℯ\x12(2·π)/(3)·𝐢\x13", "3·ℯ\x12π·𝐢\x13"}; + const char * solutions2Polar[] = {"ℯ^\x12-(2·π)/(3)·𝐢\x13","ℯ^\x12(2·π)/(3)·𝐢\x13", "3·ℯ^\x12π·𝐢\x13"}; assert_equation_system_exact_solve_to(equations2, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions2Polar, 3); // x^2-√(-1)=0 - const char * solutions3Polar[] = {"ℯ\x12-(3·π)/(4)·𝐢\x13", "ℯ\x12(π)/(4)·𝐢\x13", "4·ℯ\x12(π)/(2)·𝐢\x13"}; + const char * solutions3Polar[] = {"ℯ^\x12-(3·π)/(4)·𝐢\x13", "ℯ^\x12(π)/(4)·𝐢\x13", "4·ℯ^\x12(π)/(2)·𝐢\x13"}; assert_equation_system_exact_solve_to(equations3, EquationStore::Error::NoError, EquationStore::Type::PolynomialMonovariable, (const char **)variablesx, solutions3Polar, 3); } diff --git a/ion/include/ion/unicode/code_point.h b/ion/include/ion/unicode/code_point.h index e8b7cb5aa..a736160d0 100644 --- a/ion/include/ion/unicode/code_point.h +++ b/ion/include/ion/unicode/code_point.h @@ -28,10 +28,8 @@ static constexpr CodePoint UCodePointLineFeed = 0xa; // 0x11 to 0x15 are not used, so we can use them for another purpose static constexpr CodePoint UCodePointEmpty = 0x11; // Used to be parsed into EmptyExpression -static constexpr CodePoint UCodePointLeftSuperscript = 0x12; // Used to parse Power -static constexpr CodePoint UCodePointRightSuperscript = 0x13; // Used to parse Power -static constexpr CodePoint UCodePointLeftSystemParenthesis = 0x14; // Used for serialization -static constexpr CodePoint UCodePointRightSystemParenthesis = 0x15; // Used for serialization +static constexpr CodePoint UCodePointLeftSystemParenthesis = 0x12; // Used for serialization +static constexpr CodePoint UCodePointRightSystemParenthesis = 0x13; // Used for serialization static constexpr CodePoint UCodePointMiddleDot = 0xb7; // · static constexpr CodePoint UCodePointMultiplicationSign = 0xd7; // × diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index cc9f502d3..62e79e9d8 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -58,11 +58,10 @@ Expression Parser::parseUntil(Token::Type stoppingType) { &Parser::parseUnexpected, // Token::EndOfStream &Parser::parseStore, // Token::Store &Parser::parseEqual, // Token::Equal - &Parser::parseUnexpected, // Token::RightSuperscript + &Parser::parseUnexpected, // Token::RightSystemParenthesis &Parser::parseUnexpected, // Token::RightBracket &Parser::parseUnexpected, // Token::RightParenthesis &Parser::parseUnexpected, // Token::RightBrace - &Parser::parseUnexpected, // Token::RightSystemParenthesis &Parser::parseUnexpected, // Token::Comma &Parser::parsePlus, // Token::Plus &Parser::parseMinus, // Token::Minus @@ -71,7 +70,7 @@ Expression Parser::parseUntil(Token::Type stoppingType) { &Parser::parseImplicitTimes, // Token::ImplicitTimes &Parser::parseCaret, // Token::Power &Parser::parseBang, // Token::Bang - &Parser::parseLeftSuperscript, // Token::LeftSuperscript + &Parser::parseCaretWithParenthesis, // Token::CaretWithParenthesis &Parser::parseMatrix, // Token::LeftBracket &Parser::parseLeftParenthesis, // Token::LeftParenthesis &Parser::parseUnexpected, // Token::LeftBrace @@ -215,6 +214,24 @@ void Parser::parseCaret(Expression & leftHandSide, Token::Type stoppingType) { } } +void Parser::parseCaretWithParenthesis(Expression & leftHandSide, Token::Type stoppingType) { + if (leftHandSide.isUninitialized()) { + m_status = Status::Error; // Power must have a left operand + return; + } + Token::Type endToken = Token::Type::RightSystemParenthesis; + Expression rightHandSide = parseUntil(endToken); + if (m_status != Status::Progress) { + return; + } + if (!popTokenIfType(endToken)) { + m_status = Status::Error; // Right system parenthesis missing + return; + } + leftHandSide = Power::Builder(leftHandSide, rightHandSide); + isThereImplicitMultiplication(); +} + void Parser::parseEqual(Expression & leftHandSide, Token::Type stoppingType) { if (leftHandSide.isUninitialized()) { m_status = Status::Error; // Equal must have a left operand @@ -259,23 +276,6 @@ void Parser::parseStore(Expression & leftHandSide, Token::Type stoppingType) { leftHandSide = Store::Builder(leftHandSide, static_cast(rightHandSide)); } -void Parser::parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppingType) { - if (leftHandSide.isUninitialized()) { - m_status = Status::Error; // Power must have a left operand - return; - } - Expression rightHandSide = parseUntil(Token::RightSuperscript); - if (m_status != Status::Progress) { - return; - } - if (!popTokenIfType(Token::RightSuperscript)) { - m_status = Status::Error; // Right superscript marker missing. - return; - } - leftHandSide = Power::Builder(leftHandSide, rightHandSide); - isThereImplicitMultiplication(); -} - bool Parser::parseBinaryOperator(const Expression & leftHandSide, Expression & rightHandSide, Token::Type stoppingType) { if (leftHandSide.isUninitialized()) { m_status = Status::Error; // Left-hand side missing. diff --git a/poincare/src/parsing/parser.h b/poincare/src/parsing/parser.h index dd08a501a..3bbc9c917 100644 --- a/poincare/src/parsing/parser.h +++ b/poincare/src/parsing/parser.h @@ -60,6 +60,7 @@ private: void parseSlash(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseImplicitTimes(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseCaret(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); + void parseCaretWithParenthesis(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseEqual(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseStore(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); void parseLeftSuperscript(Expression & leftHandSide, Token::Type stoppingType = (Token::Type)0); diff --git a/poincare/src/parsing/token.h b/poincare/src/parsing/token.h index 2401020eb..06fd47738 100644 --- a/poincare/src/parsing/token.h +++ b/poincare/src/parsing/token.h @@ -24,13 +24,10 @@ public: * token of lesser precedence than Equal, and this prevents expressions * such as "3=4>a". Tokenizer::parseStore uses a special algorithm that * prevents (3>4=a). */ - RightSuperscript, - /* Superscript marks the limit of a power. For instance: - * 2 LeftSuperscript 3! RightSuperscript ! is (2^(3!))! */ + RightSystemParenthesis, RightBracket, RightParenthesis, RightBrace, - RightSystemParenthesis, Comma, Plus, Minus, @@ -43,7 +40,7 @@ public: * in order to allow the Parser to insert such Tokens where needed. */ Caret, Bang, - LeftSuperscript, + CaretWithParenthesis, LeftBracket, LeftParenthesis, LeftBrace, diff --git a/poincare/src/parsing/tokenizer.cpp b/poincare/src/parsing/tokenizer.cpp index 37f8b6497..2f7ce02ac 100644 --- a/poincare/src/parsing/tokenizer.cpp +++ b/poincare/src/parsing/tokenizer.cpp @@ -145,14 +145,11 @@ Token Tokenizer::popToken() { return Token(Token::RightSystemParenthesis); } if (c == '^') { + if (canPopCodePoint(UCodePointLeftSystemParenthesis)) { + return Token(Token::CaretWithParenthesis); + } return Token(Token::Caret); } - if (c == UCodePointLeftSuperscript) { - return Token(Token::LeftSuperscript); - } - if (c == UCodePointRightSuperscript) { - return Token(Token::RightSuperscript); - } if (c == '!') { return Token(Token::Bang); } diff --git a/poincare/src/vertical_offset_layout.cpp b/poincare/src/vertical_offset_layout.cpp index 7121c14bc..ed5f46cc3 100644 --- a/poincare/src/vertical_offset_layout.cpp +++ b/poincare/src/vertical_offset_layout.cpp @@ -173,13 +173,14 @@ int VerticalOffsetLayoutNode::serialize(char * buffer, int bufferSize, Preferenc return numberOfChar; } assert(m_position == Position::Superscript); - /* If the layout is a superscript, write: - * "UCodePointLeftSuperscript indice UCodePointRightSuperscript" */ - int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, UCodePointLeftSuperscript); + // If the layout is a superscript, write: '^' 'System(' indice 'System)' + int numberOfChar = SerializationHelper::CodePoint(buffer, bufferSize, '^'); + if (numberOfChar >= bufferSize-1) { return bufferSize-1; } + numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, UCodePointLeftSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } numberOfChar += const_cast(this)->indiceLayout()->serialize(buffer+numberOfChar, bufferSize-numberOfChar, floatDisplayMode, numberOfSignificantDigits); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } - numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, UCodePointRightSuperscript); + numberOfChar += SerializationHelper::CodePoint(buffer+numberOfChar, bufferSize-numberOfChar, UCodePointRightSystemParenthesis); if (numberOfChar >= bufferSize-1) { return bufferSize-1; } buffer[numberOfChar] = 0; diff --git a/poincare/test/vertical_offset_layout.cpp b/poincare/test/vertical_offset_layout.cpp index 7da0bbae7..7b49f98c3 100644 --- a/poincare/test/vertical_offset_layout.cpp +++ b/poincare/test/vertical_offset_layout.cpp @@ -14,7 +14,7 @@ QUIZ_CASE(poincare_vertical_offset_layout_serialize) { VerticalOffsetLayoutNode::Position::Superscript ) ); - assert(UCodePointLeftSuperscript == '\x12'); - assert(UCodePointRightSuperscript == '\x13'); - assert_expression_layout_serialize_to(layout, "2\x12x+5\x13"); + assert(UCodePointLeftSystemParenthesis == '\x12'); + assert(UCodePointRightSystemParenthesis == '\x13'); + assert_expression_layout_serialize_to(layout, "2^\x12x+5\x13"); } From 2ff03bb6a082e317556ef041a824e4b8cc529b8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 25 Jun 2019 10:39:58 +0200 Subject: [PATCH 029/111] [poincare/parser] Pop corresponding types of parentheses --- poincare/src/parsing/parser.cpp | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index 62e79e9d8..649b3193f 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -412,9 +412,13 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, m_status = Status::Error; // Identifier name too long. return; } - if (!popTokenIfType(Token::LeftParenthesis) && !popTokenIfType(Token::LeftSystemParenthesis)) { - leftHandSide = Symbol::Builder(name, length); - return; + bool poppedParenthesisIsSystem = false; + if (!popTokenIfType(Token::LeftParenthesis)) { + if (!popTokenIfType(Token::LeftSystemParenthesis)) { + leftHandSide = Symbol::Builder(name, length); + return; + } + poppedParenthesisIsSystem = true; } Expression parameter = parseCommaSeparatedList(); if (m_status != Status::Progress) { @@ -428,10 +432,13 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, parameter = parameter.childAtIndex(0); if (parameter.type() == ExpressionNode::Type::Symbol && strncmp(static_cast(parameter).name(), name, length) == 0) { m_status = Status::Error; // Function and variable must have distinct names. - } else if (!popTokenIfType(Token::RightParenthesis) && !popTokenIfType(Token::RightSystemParenthesis)) { - m_status = Status::Error; // Right parenthesis missing. } else { - leftHandSide = Function::Builder(name, length, parameter); + Token::Type correspondingRightParenthesis = poppedParenthesisIsSystem ? Token::Type::RightSystemParenthesis : Token::Type::RightParenthesis; + if (!popTokenIfType(correspondingRightParenthesis)) { + m_status = Status::Error; // Right parenthesis missing or wrong type of right parenthesis + } else { + leftHandSide = Function::Builder(name, length, parameter); + } } } @@ -455,19 +462,24 @@ void Parser::parseIdentifier(Expression & leftHandSide, Token::Type stoppingType } Expression Parser::parseFunctionParameters() { - if (!popTokenIfType(Token::LeftParenthesis) && !popTokenIfType(Token::LeftSystemParenthesis)) { - m_status = Status::Error; // Left parenthesis missing. - return Expression(); + bool poppedParenthesisIsSystem = false; + if (!popTokenIfType(Token::LeftParenthesis)) { + if (!popTokenIfType(Token::LeftSystemParenthesis)) { + m_status = Status::Error; // Left parenthesis missing. + return Expression(); + } + poppedParenthesisIsSystem = true; } - if (popTokenIfType(Token::RightParenthesis) || popTokenIfType(Token::RightSystemParenthesis) ) { + Token::Type correspondingRightParenthesis = poppedParenthesisIsSystem ? Token::Type::RightSystemParenthesis : Token::Type::RightParenthesis; + if (popTokenIfType(correspondingRightParenthesis)) { return Matrix::Builder(); // The function has no parameter. } Expression commaSeparatedList = parseCommaSeparatedList(); if (m_status != Status::Progress) { return Expression(); } - if (!popTokenIfType(Token::RightParenthesis) && !popTokenIfType(Token::RightSystemParenthesis)) { - m_status = Status::Error; // Right parenthesis missing. + if (!popTokenIfType(correspondingRightParenthesis)) { + m_status = Status::Error; // Right parenthesis missing or wrong type of right parenthesis return Expression(); } return commaSeparatedList; From 596a4385570941d6d88709fea31360c66af6b08c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 26 Jun 2019 10:05:13 +0200 Subject: [PATCH 030/111] [poincare/parser] Comment about parseCaretWithParenthesis --- poincare/src/parsing/parser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index 649b3193f..7a32b7cd0 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -215,6 +215,10 @@ void Parser::parseCaret(Expression & leftHandSide, Token::Type stoppingType) { } void Parser::parseCaretWithParenthesis(Expression & leftHandSide, Token::Type stoppingType) { + /* When parsing 2^(4) ! (with system parentheses), the factorial should stay + * out of the power. To do this, we tokenized ^( as one token that should be + * matched by a closing parenthesis. Otherwise, the ! would take precendence + * over the power. */ if (leftHandSide.isUninitialized()) { m_status = Status::Error; // Power must have a left operand return; From 02982910434f54727bcb3e67483ddb4464c19f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 26 Jun 2019 10:41:16 +0200 Subject: [PATCH 031/111] [poincare/parser] Comment and new test about system parentheses --- poincare/src/parsing/parser.cpp | 5 +++++ poincare/src/serialization_helper.cpp | 3 +++ poincare/test/layouts.cpp | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/poincare/src/parsing/parser.cpp b/poincare/src/parsing/parser.cpp index 7a32b7cd0..48beae151 100644 --- a/poincare/src/parsing/parser.cpp +++ b/poincare/src/parsing/parser.cpp @@ -417,6 +417,9 @@ void Parser::parseCustomIdentifier(Expression & leftHandSide, const char * name, return; } bool poppedParenthesisIsSystem = false; + /* If the identifier is followed by parentheses it is a function, else it is a + * symbol. The parentheses can be system parentheses, if serialized using + * SerializationHelper::Prefix. */ if (!popTokenIfType(Token::LeftParenthesis)) { if (!popTokenIfType(Token::LeftSystemParenthesis)) { leftHandSide = Symbol::Builder(name, length); @@ -467,6 +470,8 @@ void Parser::parseIdentifier(Expression & leftHandSide, Token::Type stoppingType Expression Parser::parseFunctionParameters() { bool poppedParenthesisIsSystem = false; + /* The function parentheses can be system parentheses, if serialized using + * SerializationHelper::Prefix.*/ if (!popTokenIfType(Token::LeftParenthesis)) { if (!popTokenIfType(Token::LeftSystemParenthesis)) { m_status = Status::Error; // Left parenthesis missing. diff --git a/poincare/src/serialization_helper.cpp b/poincare/src/serialization_helper.cpp index 34f25f169..ffe45b6f0 100644 --- a/poincare/src/serialization_helper.cpp +++ b/poincare/src/serialization_helper.cpp @@ -80,6 +80,9 @@ int InfixPrefix( int numberOfChar = 0; + /* For Prefix, we use system parentheses so that, for instance, |3)+(1| is not + * parsable after serialization.*/ + if (prefix) { // Prefix: Copy the operator name numberOfChar = strlcpy(buffer, operatorName, bufferSize); diff --git a/poincare/test/layouts.cpp b/poincare/test/layouts.cpp index c68a27420..5509a0fdd 100644 --- a/poincare/test/layouts.cpp +++ b/poincare/test/layouts.cpp @@ -423,4 +423,18 @@ QUIZ_CASE(poincare_unparsable_layouts) { HorizontalLayout::Builder(children, childrenCount)); assert_layout_is_not_parsed(l); } + + { + // |3)+(1| + constexpr int childrenCount = 5; + Layout children[childrenCount] = { + CodePointLayout::Builder('3'), + RightParenthesisLayout::Builder(), + CodePointLayout::Builder('+'), + LeftParenthesisLayout::Builder(), + CodePointLayout::Builder('1')}; + + Layout l = AbsoluteValueLayout::Builder(HorizontalLayout::Builder(children, childrenCount)); + assert_layout_is_not_parsed(l); + } } From 2ae4b639515e6050dbd426d8a0de737e420d8a8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 26 Jun 2019 16:45:33 +0200 Subject: [PATCH 032/111] Revert "[kandinsky/fonts/LargeFont.ttf] Change the glyphs of 0 and 3 characters" This reverts commit cd4260494a9098c54460ff649282ab9a4f8eb896. --- kandinsky/fonts/LargeFont.ttf | Bin 219324 -> 219444 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/kandinsky/fonts/LargeFont.ttf b/kandinsky/fonts/LargeFont.ttf index 0dda11f09a115a4158dae88b284eac6dd00cd8ea..46b67f74d6733ff75cd16c128336bd3c8d9a4daf 100644 GIT binary patch delta 3440 zcmZYCUrRW z$4q$O!I_ZOWO(3#wmdL(V>S{0G!TmsE2hL!iS;T_v$t-~ zT~%M^YY?4CV(s2lSM7D|JLF;=5Xl+c>p8q<*NGk*dn2M}BDK4#YvOLdw?K5LkJy@8 z0#S7{?uy=-WSv%9=kt%PeKk=Y)uAbogegz`uIgE{&$>m=PKels>#F_UneRu%upZ!m zeSdY`?pY`AWJ*+Gm55&R)*tkxUrGLnL@mmDVff8q^U^PaizQc9Q#@v7%*@o3W$Dv@ z^79JT6s%djYJS4>pLi>K(W_S#tjW(?mY$jtGc(>gzaTY#wV5cerKM!0EwwK!NKAY< zIcLSjZL9K=V`oH1&xpN$epgLKhGXUS9XYv~7ybTiS@D)x7E65A=FK}_t9B&BXXb8M zl4Va=|M24FOR7sA4K|mQY%OnSD1ODm=s)c|VO|SrjJ8e>$0!WMV5#}jH~*RAzmvo) z`({vvjAz!Egm0dsAhfSEHzzvUS=g{LKR+eKYPH)_vX`W$ugzWQSX))F_J}JxD@xPT z*Ew=u-LkwWIk|9EX6lA{^OBO5CMPd^=)t(Sl=+J?7ud40p73TzKaiQRVV%P<$FgOO z$V*)zbE+$(Keh!=*u7W2MG%vB0prNGrH1ki>7 zOo{nj5{giTfS4g_{k}}hHR9K}{{wGg*aGseXM?wLy$Q#~1h4Zne>{o_F*i7HgZmL1 zC@@0v4>UpSX@i!-W=f zAR^{tYJS|t_y2^=Pnyv!=2MD&I(=oB@pdt{v%%}T9R{&K7orz5xKoB9F%uR9#QY@| zPTUpq*Q4kc^BJ+vTxb;&Auqykkx4Os^I%lW=T5%==QR9#9@xC=15a{~ja7a zs6d;TFRY;17d*jaHhRVUGY*w#!HAeIGeFLloc$^frpoKewWY=`LFe$fZgK;k@)Xq-*-K?^ASt$^r5K2a-;tV5#lBccg3 zn@^6dLUaN93u{CZ*-tztnnbOnyQ0Z)CD3i1=esOWMlIJ~?GG+BOEG^-GPbc1zv9@x*O(25!a&9!|r6==xaDWW5{ITudZqqJbZuWF>Wa890rqaq{zk$P-tTx z#zh|yuzsWyL!ytyp#nVNCeCgmwu!SPoGsyO3ArV197UICX*S3$CAXB^QgU77y2|0H?!W%dNb>9N5cp5%8F16;$`PBCi*!0k2_F>b`aY_(=Fs}31LEX zD-E|2+ggTZ^kbawUv2@1%Ux(fhv+t9+lp}%46|)g^a&@L!Tu9{py+lAZufxuifGiL z6a66eqzeH|i9SW%Qw;YML+=pqKs$otqLoZtIVk#cF=)1vA$CSYzvITJXcgD0;~?i5 znmkj87I5~ve$i(IsdY5bFg8_e_fJO#@B$lDn7qUShQrto0&f1g!!ACv8? zgdfMzjZx9(EXac!GvF1#jxlh3yMI|Lkw_;vwk}$=;uxN z`$Z4Of%Reb4@X3wcfbqQ&kupR4Ng!u*x=`e;tgyz(6nJ(G{9>NP&D8I0|nR*bc4fz z3DHJ|XiNh|8Y$99jYe`BsnJM{Mrs_P#t~{9Vb~*;@Zp%~i*2GUouV&?F~IkKndDZI zTS;yuxz&wkbYT!Qe8q;s|7oLXM>&Q?e^!f#=+B!#?l1B{qfQ6N>l_pf^@+aD-pLx# zH#$Va1EO!GA%FRZm(} delta 3329 zcmZYAUr@ym7a_U`Wa*Sn zm<|ujz*KB`U|O2+z!)&Au1XaXRIJ)!OYNp1mZX@FNE4cDDmC=a*Y=?gb>?&T{?70G z&N=tqQ9Y+-_x8+g3UlXrL?kGEW7?*b%U0SXAUBWort}>sV(=rE7G}iTU!J4%Lfl_Y5mFAZe z&Ny{{i3B_~Dx!DF%PK14ZbklB0wR0A?>p@?ub{++%aOJU{xG$J5rQ z0(620dzUl))b1zNUxzk$L7#s5ToE@H3SOb$m3k1oD&Wx73^4W8R`i3tYdpcVR8a6* z7l>bDfB_4lKzx7(*Qs$m7Sy;tDdtxl=*Nhd8|>ZSjoom<%|tgSe2d^MhPdSb4Szi# z<~Q|X25s<*xlMuF6u3Pq=C>BaA_w*8KtD#s{LUg~h+0EKVt!Bj4)=F>6MtwD<0Iea z0dM8KAVi6AzsJ-3F&LHL!28_4-wp~4(|nl2A5i22e(y5eUH0zM=EBs53Pv<{ulunSX}B-N}VU|B6B?a!}6S+<1(O8W(PgY5_(>19C(y zq39KzWJCm2ot=d)(Z@)9 z%rE+QyJ$$0=o|`v%YrG7&_;W-q#1G$sdQ zqOq~aLkp<0i2Fqy7!r*O0d?bwMHlCS{CMic`$U%nxw)jmi8gR}X%J|#v<7{m%LI0? zUe+s`zug}Xt{%Pc!O!=%hl|=NYR?0c+9_i128GsVq8triy}=3xS}`p898Z{L2eCBHrg1in zvuWg}(R5QVlHn0eCpVqkbaK*w6H0RCH@Rh;60mR`Rx`q7pRRMr_-V==Km~p`7o(y$KxNJ}8xiEEZE^dl`mu9;eVz&!pqTh3ZUq=+kanQukC;Cz-IQz1o0Y1?^@!;H^ z0nt3_bNQVj1Az{yKDl zrbXly5icTEM8Tp-QD-W0;X*6C@L^K)KsZv73m4!2KpQtqc3?#Gpdbo%IMIY&jENqi z(IFd%A0mFp3(gb=gM!6*Xawy2Jw;xbYobwlz6EX3{YCn_b+9m)F)ad;3>=4 zD60eUG76Q4z>adXV^H)J3sO;x4h)GNCU%&Hhj~MXTi^u^D`;3jyuyKcP`843C3P#^ zHZD%IVE}&7SL2ZbhIrM3QPCq2$U_tQMUPVSC<7ej?9on8(8Zf@WuX>V6xuV^fqCM>OjElaVAnM5xJ>4aG z#%AY2;#sCT+XfDJN%S^>xOWIlel8vicAlxv^MAj{BfA~_UmPDC(zyZF$3HqdHl&&L F{|2QpM*aW* From c7bde32d65781fdcf69097d8c7ef005e07834e63 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Wed, 26 Jun 2019 17:34:19 +0200 Subject: [PATCH 033/111] [kandinsky] Fix the 0 glyph in the large font --- kandinsky/fonts/LargeFont.ttf | Bin 219444 -> 219444 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/kandinsky/fonts/LargeFont.ttf b/kandinsky/fonts/LargeFont.ttf index 46b67f74d6733ff75cd16c128336bd3c8d9a4daf..a248bbb6d2c2457a8f2800fb107fb89103f6f135 100644 GIT binary patch delta 80 zcmV-W0I&bFvJJGd4Uk|I1O>|w0002o00O%3Xk}q!5fBd}fpoQW0VA&iCp8zBny&#> m1c?lC42Sct0k`w70@)-4x{Qu@m(bJ#6$3e3zPISq0!)N_79Oqu delta 80 zcmV-W0I&bFvJJGd4Uk|IW3Rs$0002o00O%3Xk}q!5b4etfpoQW0VA&iBQ-OZny&#> m1eI(60EhFh0k`w70@)-4`-Lcbm(bJ#6$29+w72Ng0!)MxFCeV| From 7891cf418204b3b5668df3c095c5dfaef1071663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 10 Jul 2019 17:28:53 +0200 Subject: [PATCH 034/111] [apps/shared] Fix ExpressionListController: the cell heights memoization was corrupted --- apps/shared/expression_model_list_controller.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/shared/expression_model_list_controller.cpp b/apps/shared/expression_model_list_controller.cpp index 1bca31721..e635a16ff 100644 --- a/apps/shared/expression_model_list_controller.cpp +++ b/apps/shared/expression_model_list_controller.cpp @@ -19,8 +19,12 @@ ExpressionModelListController::ExpressionModelListController(Responder * parentR void ExpressionModelListController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { int currentSelectedRow = selectedRow(); - // Update m_cumulatedHeightForSelectedIndex if we scrolled one cell up/down - if (currentSelectedRow >= 0 && currentSelectedRow == previousSelectedCellY + 1) { + /* Update m_cumulatedHeightForSelectedIndex if we scrolled one cell up/down. + * We want previousSelectedCellY >= 0 and currentSelectedRow >= 0 to ensure + * that a cell is selected before and after the change. + * (previousSelectedCellY >= 0 condition is enough as + * currentSelectedRow > previousSelectedCellY) */ + if (previousSelectedCellY >= 0 && currentSelectedRow == previousSelectedCellY + 1) { /* We selected the cell under the previous cell. Shift the memoized cell * heights. */ shiftMemoization(true); @@ -32,6 +36,8 @@ void ExpressionModelListController::tableViewDidChangeSelection(SelectableTableV assert(currentSelectedRow == 0); m_cumulatedHeightForSelectedIndex = 0; } + /* We ensure that a cell is selected before and after the selection change by + * checking that previousSelectedCellY > currentSelectedRow >= 0. */ } else if (currentSelectedRow >= 0 && currentSelectedRow == previousSelectedCellY - 1) { /* We selected the cell above the previous cell. Shift the memoized cell * heights. */ From 9a2524908865efca044db27efc8c1fbbaa27eb68 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 14:05:05 +0200 Subject: [PATCH 035/111] [apps/shared/store_controller] Simpler access to AppsContainer * --- apps/shared/store_controller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index 5fe16e690..484c61f2c 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -258,7 +258,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio constexpr static int k_maxSizeOfStoreSymbols = 3; // "V1", "N1", "X1", "Y1" char variables[Expression::k_maxNumberOfVariables][k_maxSizeOfStoreSymbols]; variables[0][0] = 0; - AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); + AppsContainer * appsContainer = (AppsContainer *)app()->container(); int nbOfVariables = formula.getVariables(*(appsContainer->globalContext()), isVariable, (char *)variables, k_maxSizeOfStoreSymbols); (void) nbOfVariables; // Remove compilation warning of nused variable assert(nbOfVariables >= 0); From 35467885739b1b113cac3a6902997bf654aa7a16 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 14:40:04 +0200 Subject: [PATCH 036/111] [apps/shared/input_event_handler_delegate_app] Simpler (and protected) access to AppsContainer * --- apps/shared/input_event_handler_delegate_app.cpp | 2 +- apps/shared/input_event_handler_delegate_app.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/shared/input_event_handler_delegate_app.cpp b/apps/shared/input_event_handler_delegate_app.cpp index 47c6dc2a0..3b9ed0594 100644 --- a/apps/shared/input_event_handler_delegate_app.cpp +++ b/apps/shared/input_event_handler_delegate_app.cpp @@ -14,7 +14,7 @@ InputEventHandlerDelegateApp::InputEventHandlerDelegateApp(Container * container } AppsContainer * InputEventHandlerDelegateApp::container() { - return (AppsContainer *)(app()->container()); + return static_cast(const_cast(::App::container())); } Toolbox * InputEventHandlerDelegateApp::toolboxForInputEventHandler(InputEventHandler * textInput) { diff --git a/apps/shared/input_event_handler_delegate_app.h b/apps/shared/input_event_handler_delegate_app.h index 75f502988..4c5c238cb 100644 --- a/apps/shared/input_event_handler_delegate_app.h +++ b/apps/shared/input_event_handler_delegate_app.h @@ -10,11 +10,11 @@ namespace Shared { class InputEventHandlerDelegateApp : public ::App, public InputEventHandlerDelegate { public: virtual ~InputEventHandlerDelegateApp() = default; - AppsContainer * container(); Toolbox * toolboxForInputEventHandler(InputEventHandler * textInput) override; NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; protected: InputEventHandlerDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController); + AppsContainer * container(); }; } From 268ad3f3bac973e556fdad18e8e693faffa14c9e Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 16 May 2019 15:26:04 +0200 Subject: [PATCH 037/111] Access the shared container from escher and apps --- apps/apps_container.cpp | 1 + apps/apps_container.h | 3 +++ escher/include/escher/container.h | 8 ++++++++ escher/src/container.cpp | 3 +++ 4 files changed, 15 insertions(+) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index 6e7cef01d..ce1a9135a 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -241,6 +241,7 @@ bool AppsContainer::switchTo(App::Snapshot * snapshot) { } void AppsContainer::run() { + setSharedContainer(this); window()->setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height)); refreshPreferences(); diff --git a/apps/apps_container.h b/apps/apps_container.h index a46dcebfc..c8236271b 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -24,6 +24,9 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::StorageDelegate { public: + static AppsContainer * sharedAppsContainer() { + return static_cast(Container::sharedContainer()); + } AppsContainer(); static bool poincareCircuitBreaker(); virtual int numberOfApps() = 0; diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index e4f33604e..4111aaa2b 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -17,6 +17,10 @@ class Container : public RunLoop { public: + static Container * sharedContainer() { + assert(s_sharedContainer); + return s_sharedContainer; + } Container(); virtual ~Container(); Container(const Container& other) = delete; @@ -30,6 +34,9 @@ public: virtual bool switchTo(App::Snapshot * snapshot); protected: virtual Window * window() = 0; + void setSharedContainer(Container * container) { + s_sharedContainer = container; + } private: void step(); int numberOfTimers() override; @@ -37,6 +44,7 @@ private: virtual int numberOfContainerTimers(); virtual Timer * containerTimerAtIndex(int i); App * m_activeApp; + static Container * s_sharedContainer; }; #endif diff --git a/escher/src/container.cpp b/escher/src/container.cpp index fd92857a4..0bf23e636 100644 --- a/escher/src/container.cpp +++ b/escher/src/container.cpp @@ -7,6 +7,9 @@ Container::Container() : { } +// Initialize private static member +Container * Container::s_sharedContainer = nullptr; + Container::~Container() { if (m_activeApp) { m_activeApp->~App(); From eb3da7f395d8885e4f855c36bc8f7f2812fbb768 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 15:06:23 +0200 Subject: [PATCH 038/111] [apps] Substitute "app()->container()" by "AppsContainer::sharedAppsContainer()" --- apps/code/console_controller.cpp | 6 +++--- apps/code/menu_controller.cpp | 6 +++--- apps/code/sandbox_controller.cpp | 2 +- apps/exam_pop_up_controller.cpp | 5 ++--- apps/graph/list/list_controller.cpp | 6 +++--- apps/hardware_test/pop_up_controller.cpp | 3 +-- apps/on_boarding/language_controller.cpp | 2 +- apps/on_boarding/pop_up_controller.cpp | 2 +- apps/regression/calculation_controller.cpp | 2 +- apps/regression/go_to_parameter_controller.cpp | 2 +- apps/regression/graph_controller.cpp | 2 +- apps/regression/graph_view.cpp | 2 +- apps/regression/store_controller.cpp | 2 +- apps/settings/sub_menu/exam_mode_controller.cpp | 3 +-- apps/settings/sub_menu/preferences_controller.cpp | 3 +-- apps/shared/language_controller.cpp | 3 +-- apps/shared/store_controller.cpp | 2 +- apps/statistics/store_controller.cpp | 2 +- 18 files changed, 25 insertions(+), 30 deletions(-) diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index bc6fdf4bc..ebcb7a24a 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -90,7 +90,7 @@ void ConsoleController::terminateInputLoop() { } const char * ConsoleController::inputText(const char * prompt) { - AppsContainer * a = (AppsContainer *)(app()->container()); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); m_inputRunLoopActive = true; const char * promptText = prompt; @@ -119,10 +119,10 @@ const char * ConsoleController::inputText(const char * prompt) { // Reload the history m_selectableTableView.reloadData(); m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines()); - a->redrawWindow(); + appsContainer->redrawWindow(); // Launch a new input loop - a->runWhile([](void * a){ + appsContainer->runWhile([](void * a){ ConsoleController * c = static_cast(a); return c->inputRunLoopActive(); }, this); diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index 80e8fd4af..c9378bcbe 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -121,7 +121,7 @@ bool MenuController::handleEvent(Ion::Events::Event event) { void MenuController::renameSelectedScript() { assert(m_selectableTableView.selectedRow() >= 0); assert(m_selectableTableView.selectedRow() < m_scriptStore->numberOfScripts()); - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); m_selectableTableView.selectCellAtLocation(0, (m_selectableTableView.selectedRow())); ScriptNameCell * myCell = static_cast(m_selectableTableView.selectedCell()); app()->setFirstResponder(myCell); @@ -338,7 +338,7 @@ bool MenuController::textFieldDidFinishEditing(TextField * textField, const char m_selectableTableView.selectedCell()->setHighlighted(true); reloadConsole(); app()->setFirstResponder(&m_selectableTableView); - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } else if (error == Script::ErrorStatus::NameTaken) { app()->displayWarning(I18n::Message::NameTaken); @@ -422,7 +422,7 @@ bool MenuController::privateTextFieldDidAbortEditing(TextField * textField, bool m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); app()->setFirstResponder(&m_selectableTableView); } - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } diff --git a/apps/code/sandbox_controller.cpp b/apps/code/sandbox_controller.cpp index 12b5f0332..5b056c53b 100644 --- a/apps/code/sandbox_controller.cpp +++ b/apps/code/sandbox_controller.cpp @@ -48,7 +48,7 @@ bool SandboxController::handleEvent(Ion::Events::Event event) { } void SandboxController::redrawWindow() { - static_cast(const_cast(app()->container()))->redrawWindow(); + AppsContainer::sharedAppsContainer()->redrawWindow(); } } diff --git a/apps/exam_pop_up_controller.cpp b/apps/exam_pop_up_controller.cpp index b72bca2b5..a4568833b 100644 --- a/apps/exam_pop_up_controller.cpp +++ b/apps/exam_pop_up_controller.cpp @@ -47,8 +47,7 @@ bool ExamPopUpController::handleEvent(Ion::Events::Event event) { ExamPopUpController::ContentView::ContentView(Responder * parentResponder) : m_cancelButton(parentResponder, I18n::Message::Cancel, Invocation([](void * context, void * sender) { - ExamPopUpController * controller = (ExamPopUpController *)context; - Container * container = (Container *)controller->app()->container(); + AppsContainer * container = AppsContainer::sharedAppsContainer(); container->activeApp()->dismissModalViewController(); return true; }, parentResponder), KDFont::SmallFont), @@ -56,7 +55,7 @@ ExamPopUpController::ContentView::ContentView(Responder * parentResponder) : ExamPopUpController * controller = (ExamPopUpController *)context; GlobalPreferences::ExamMode nextExamMode = controller->isActivatingExamMode() ? GlobalPreferences::ExamMode::Activate : GlobalPreferences::ExamMode::Deactivate; GlobalPreferences::sharedGlobalPreferences()->setExamMode(nextExamMode); - AppsContainer * container = (AppsContainer *)controller->app()->container(); + AppsContainer * container = AppsContainer::sharedAppsContainer(); if (controller->isActivatingExamMode()) { container->reset(); Ion::LED::setColor(KDColorRed); diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index df1bfa9c1..5d7a26a02 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -38,7 +38,7 @@ void ListController::renameSelectedFunction() { computeTitlesColumnWidth(true); selectableTableView()->reloadData(); - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); TextFieldFunctionTitleCell * selectedTitleCell = (TextFieldFunctionTitleCell *)(selectableTableView()->selectedCell()); selectedTitleCell->setHorizontalAlignment(1.0f); app()->setFirstResponder(selectedTitleCell); @@ -91,7 +91,7 @@ bool ListController::textFieldDidFinishEditing(TextField * textField, const char if (selectTab) { m_selectableTableView.parentResponder()->handleEvent(event); } - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } else if (error == Ion::Storage::Record::ErrorStatus::NameTaken) { app()->displayWarning(I18n::Message::NameTaken); @@ -122,7 +122,7 @@ bool ListController::textFieldDidAbortEditing(TextField * textField) { setFunctionNameInTextField(function, textField); m_selectableTableView.selectedCell()->setHighlighted(true); app()->setFirstResponder(&m_selectableTableView); - static_cast(const_cast(app()->container()))->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); + AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } diff --git a/apps/hardware_test/pop_up_controller.cpp b/apps/hardware_test/pop_up_controller.cpp index 791846dcf..c51b3dbe0 100644 --- a/apps/hardware_test/pop_up_controller.cpp +++ b/apps/hardware_test/pop_up_controller.cpp @@ -39,8 +39,7 @@ PopUpController::ContentView::ContentView(Responder * parentResponder) : return true; }, this), KDFont::SmallFont), m_okButton(this, I18n::Message::Ok, Invocation([](void * context, void * sender) { - PopUpController::ContentView * view = (PopUpController::ContentView *)context; - AppsContainer * appsContainer = (AppsContainer *)view->app()->container(); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); bool switched = appsContainer->switchTo(appsContainer->hardwareTestAppSnapshot()); assert(switched); (void) switched; // Silence compilation warning about unused variable. diff --git a/apps/on_boarding/language_controller.cpp b/apps/on_boarding/language_controller.cpp index c0c7032ba..b9326cbf1 100644 --- a/apps/on_boarding/language_controller.cpp +++ b/apps/on_boarding/language_controller.cpp @@ -17,7 +17,7 @@ void LanguageController::reinitOnBoarding() { bool LanguageController::handleEvent(Ion::Events::Event event) { if (Shared::LanguageController::handleEvent(event)) { - AppsContainer * appsContainer = (AppsContainer *)app()->container(); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); #ifdef EPSILON_BOOT_PROMPT app()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); #else diff --git a/apps/on_boarding/pop_up_controller.cpp b/apps/on_boarding/pop_up_controller.cpp index d9596863b..af60e384d 100644 --- a/apps/on_boarding/pop_up_controller.cpp +++ b/apps/on_boarding/pop_up_controller.cpp @@ -53,7 +53,7 @@ PopUpController::PopUpController(I18n::Message * messages, KDColor * colors, uin bool PopUpController::handleEvent(Ion::Events::Event event) { if (event != Ion::Events::Back && event != Ion::Events::OnOff && event != Ion::Events::USBPlug && event != Ion::Events::USBEnumeration) { app()->dismissModalViewController(); - AppsContainer * appsContainer = (AppsContainer *)app()->container(); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); if (appsContainer->activeApp()->snapshot() == appsContainer->onBoardingAppSnapshot()) { bool switched = appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0)); assert(switched); diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index 145950d19..cb1e4ea40 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -203,7 +203,7 @@ void CalculationController::willDisplayCellAtLocation(HighlightCell * cell, int Model::Type modelType = m_store->seriesRegressionType(seriesNumber); // Put dashes if regression is not defined - Poincare::Context * globContext = const_cast(static_cast(app()->container()))->globalContext(); + Poincare::Context * globContext = AppsContainer::sharedAppsContainer()->globalContext(); double * coefficients = m_store->coefficientsForSeries(seriesNumber, globContext); bool coefficientsAreDefined = true; int numberOfCoefs = m_store->modelForSeries(seriesNumber)->numberOfCoefficients(); diff --git a/apps/regression/go_to_parameter_controller.cpp b/apps/regression/go_to_parameter_controller.cpp index a2a71a7bc..5074050ad 100644 --- a/apps/regression/go_to_parameter_controller.cpp +++ b/apps/regression/go_to_parameter_controller.cpp @@ -40,7 +40,7 @@ double GoToParameterController::parameterAtIndex(int index) { bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) { assert(parameterIndex == 0); int series = m_graphController->selectedSeriesIndex(); - Poincare::Context * globContext = const_cast(static_cast(app()->container()))->globalContext(); + Poincare::Context * globContext = AppsContainer::sharedAppsContainer()->globalContext(); double unknown = m_xPrediction ? m_store->yValueForXValue(series, f, globContext) : m_store->xValueForYValue(series, f, globContext); diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index dc6fad3c9..daeeaafae 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -97,7 +97,7 @@ void GraphController::selectRegressionCurve() { // Private Poincare::Context * GraphController::globalContext() { - return const_cast(static_cast(app()->container()))->globalContext(); + return AppsContainer::sharedAppsContainer()->globalContext(); } // SimpleInteractiveCurveViewController diff --git a/apps/regression/graph_view.cpp b/apps/regression/graph_view.cpp index b08575c6c..605c61cf8 100644 --- a/apps/regression/graph_view.cpp +++ b/apps/regression/graph_view.cpp @@ -22,11 +22,11 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { drawGrid(ctx, rect); drawAxes(ctx, rect); simpleDrawBothAxesLabels(ctx, rect); + Poincare::Context * globContext = AppsContainer::sharedAppsContainer()->globalContext(); for (int series = 0; series < Store::k_numberOfSeries; series++) { if (!m_store->seriesIsEmpty(series)) { KDColor color = Palette::DataColor[series]; Model * seriesModel = m_store->modelForSeries(series); - Poincare::Context * globContext = const_cast(static_cast(m_controller->app()->container()))->globalContext(); drawCurve(ctx, rect, [](float abscissa, void * model, void * context) { Model * regressionModel = static_cast(model); double * regressionCoefficients = static_cast(context); diff --git a/apps/regression/store_controller.cpp b/apps/regression/store_controller.cpp index a7201efb7..5d237dee0 100644 --- a/apps/regression/store_controller.cpp +++ b/apps/regression/store_controller.cpp @@ -19,7 +19,7 @@ StoreController::StoreController(Responder * parentResponder, InputEventHandlerD } StoreContext * StoreController::storeContext() { - m_regressionContext.setParentContext(const_cast(static_cast(app()->container()))->globalContext()); + m_regressionContext.setParentContext(AppsContainer::sharedAppsContainer()->globalContext()); return &m_regressionContext; } diff --git a/apps/settings/sub_menu/exam_mode_controller.cpp b/apps/settings/sub_menu/exam_mode_controller.cpp index d3cc2890b..6f24abcd7 100644 --- a/apps/settings/sub_menu/exam_mode_controller.cpp +++ b/apps/settings/sub_menu/exam_mode_controller.cpp @@ -24,8 +24,7 @@ bool ExamModeController::handleEvent(Ion::Events::Event event) { if (GlobalPreferences::sharedGlobalPreferences()->examMode() == GlobalPreferences::ExamMode::Activate) { return false; } - AppsContainer * container = (AppsContainer *)(app()->container()); - container->displayExamModePopUp(true); + AppsContainer::sharedAppsContainer()->displayExamModePopUp(true); return true; } return GenericSubController::handleEvent(event); diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index 527a4a530..45b684776 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -30,8 +30,7 @@ bool PreferencesController::handleEvent(Ion::Events::Event event) { /* Generic behaviour of preference menu*/ assert(m_messageTreeModel->label() != I18n::Message::DisplayMode || selectedRow() != numberOfRows()-1); // In that case, events OK and EXE are handled by the cell setPreferenceWithValueIndex(m_messageTreeModel->label(), selectedRow()); - AppsContainer * myContainer = (AppsContainer * )app()->container(); - myContainer->refreshPreferences(); + AppsContainer::sharedAppsContainer()->refreshPreferences(); StackViewController * stack = stackController(); stack->pop(); return true; diff --git a/apps/shared/language_controller.cpp b/apps/shared/language_controller.cpp index 9dadb13a1..ee0e04084 100644 --- a/apps/shared/language_controller.cpp +++ b/apps/shared/language_controller.cpp @@ -43,8 +43,7 @@ bool LanguageController::handleEvent(Ion::Events::Event event) { GlobalPreferences::sharedGlobalPreferences()->setLanguage((I18n::Language)(selectedRow()+1)); /* We need to reload the whole title bar in order to translate both the * "Settings" title and the degree preference. */ - AppsContainer * myContainer = (AppsContainer * )app()->container(); - myContainer->reloadTitleBarView(); + AppsContainer::sharedAppsContainer()->reloadTitleBarView(); return true; } return false; diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index 484c61f2c..168d0805e 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -258,7 +258,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio constexpr static int k_maxSizeOfStoreSymbols = 3; // "V1", "N1", "X1", "Y1" char variables[Expression::k_maxNumberOfVariables][k_maxSizeOfStoreSymbols]; variables[0][0] = 0; - AppsContainer * appsContainer = (AppsContainer *)app()->container(); + AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); int nbOfVariables = formula.getVariables(*(appsContainer->globalContext()), isVariable, (char *)variables, k_maxSizeOfStoreSymbols); (void) nbOfVariables; // Remove compilation warning of nused variable assert(nbOfVariables >= 0); diff --git a/apps/statistics/store_controller.cpp b/apps/statistics/store_controller.cpp index db86f0ade..9dac9c3fe 100644 --- a/apps/statistics/store_controller.cpp +++ b/apps/statistics/store_controller.cpp @@ -22,7 +22,7 @@ StoreController::StoreController(Responder * parentResponder, InputEventHandlerD } StoreContext * StoreController::storeContext() { - m_statisticsContext.setParentContext(const_cast(static_cast(app()->container()))->globalContext()); + m_statisticsContext.setParentContext(AppsContainer::sharedAppsContainer()->globalContext()); return &m_statisticsContext; } From 3489a1a644fac693a0f9e2c5e7e88b319e76432b Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 15:38:42 +0200 Subject: [PATCH 039/111] [apps/regression] The GraphView does not need a pointer to the GraphController anymore --- apps/regression/graph_controller.cpp | 2 +- apps/regression/graph_view.cpp | 5 ++--- apps/regression/graph_view.h | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/regression/graph_controller.cpp b/apps/regression/graph_controller.cpp index daeeaafae..ab44705c8 100644 --- a/apps/regression/graph_controller.cpp +++ b/apps/regression/graph_controller.cpp @@ -18,7 +18,7 @@ GraphController::GraphController(Responder * parentResponder, InputEventHandlerD m_crossCursorView(), m_roundCursorView(), m_bannerView(this, inputEventHandlerDelegate, this), - m_view(store, m_cursor, &m_bannerView, &m_crossCursorView, this), + m_view(store, m_cursor, &m_bannerView, &m_crossCursorView), m_store(store), m_initialisationParameterController(this, m_store), m_graphOptionsController(this, inputEventHandlerDelegate, m_store, m_cursor, this), diff --git a/apps/regression/graph_view.cpp b/apps/regression/graph_view.cpp index 605c61cf8..9018154bf 100644 --- a/apps/regression/graph_view.cpp +++ b/apps/regression/graph_view.cpp @@ -8,12 +8,11 @@ using namespace Shared; namespace Regression { -GraphView::GraphView(Store * store, CurveViewCursor * cursor, BannerView * bannerView, View * cursorView, Responder * controller) : +GraphView::GraphView(Store * store, CurveViewCursor * cursor, BannerView * bannerView, View * cursorView) : CurveView(store, cursor, bannerView, cursorView), m_store(store), m_xLabels{}, - m_yLabels{}, - m_controller(controller) + m_yLabels{} { } diff --git a/apps/regression/graph_view.h b/apps/regression/graph_view.h index 27fe89dc4..aa9be68e4 100644 --- a/apps/regression/graph_view.h +++ b/apps/regression/graph_view.h @@ -1,7 +1,6 @@ #ifndef REGRESSION_GRAPH_VIEW_H #define REGRESSION_GRAPH_VIEW_H -#include #include "store.h" #include "../constant.h" #include "../shared/curve_view.h" @@ -10,14 +9,13 @@ namespace Regression { class GraphView : public Shared::CurveView { public: - GraphView(Store * store, Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView, Responder * controller); + GraphView(Store * store, Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView); void drawRect(KDContext * ctx, KDRect rect) const override; private: char * label(Axis axis, int index) const override; Store * m_store; char m_xLabels[k_maxNumberOfXLabels][k_labelBufferMaxSize]; char m_yLabels[k_maxNumberOfYLabels][k_labelBufferMaxSize]; - Responder * m_controller; }; } From d04d41431520a895dd15c4a5e5700f7182be76a7 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 15:48:33 +0200 Subject: [PATCH 040/111] [apps] Remove InputEventHandlerDelegateApp::container() --- apps/graph/app.cpp | 2 +- apps/shared/input_event_handler_delegate_app.cpp | 8 ++------ apps/shared/input_event_handler_delegate_app.h | 1 - apps/shared/text_field_delegate_app.cpp | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index 01ea5285d..1c35a84f0 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -77,7 +77,7 @@ char App::XNT() { } NestedMenuController * App::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = container()->variableBoxController(); + VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); varBox->setSender(textInput); varBox->lockDeleteEvent(VariableBoxController::Page::Function); return varBox; diff --git a/apps/shared/input_event_handler_delegate_app.cpp b/apps/shared/input_event_handler_delegate_app.cpp index 3b9ed0594..5da50cbf1 100644 --- a/apps/shared/input_event_handler_delegate_app.cpp +++ b/apps/shared/input_event_handler_delegate_app.cpp @@ -13,18 +13,14 @@ InputEventHandlerDelegateApp::InputEventHandlerDelegateApp(Container * container { } -AppsContainer * InputEventHandlerDelegateApp::container() { - return static_cast(const_cast(::App::container())); -} - Toolbox * InputEventHandlerDelegateApp::toolboxForInputEventHandler(InputEventHandler * textInput) { - Toolbox * toolbox = container()->mathToolbox(); + Toolbox * toolbox = AppsContainer::sharedAppsContainer()->mathToolbox(); toolbox->setSender(textInput); return toolbox; } NestedMenuController * InputEventHandlerDelegateApp::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = container()->variableBoxController(); + VariableBoxController * varBox = AppsContainer::sharedAppsContainer()->variableBoxController(); varBox->setSender(textInput); varBox->lockDeleteEvent(VariableBoxController::Page::RootMenu); return varBox; diff --git a/apps/shared/input_event_handler_delegate_app.h b/apps/shared/input_event_handler_delegate_app.h index 4c5c238cb..f037aaa18 100644 --- a/apps/shared/input_event_handler_delegate_app.h +++ b/apps/shared/input_event_handler_delegate_app.h @@ -14,7 +14,6 @@ public: NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; protected: InputEventHandlerDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController); - AppsContainer * container(); }; } diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index d5193d067..b073f5739 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -11,7 +11,7 @@ using namespace Poincare; namespace Shared { Context * TextFieldDelegateApp::localContext() { - return container()->globalContext(); + return AppsContainer::sharedAppsContainer()->globalContext(); } char TextFieldDelegateApp::XNT() { From 5f8a745957c1f9de3dbd592b87cd9a0dd21b2c30 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 17:07:05 +0200 Subject: [PATCH 041/111] [escher/app] Remove Container --- escher/include/escher/app.h | 2 -- escher/src/app.cpp | 5 ----- 2 files changed, 7 deletions(-) diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index 15790005a..bc83f12c0 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -57,7 +57,6 @@ public: KDCoordinate topMargin = 0, KDCoordinate leftMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate rightMargin = 0); void dismissModalViewController(); void displayWarning(I18n::Message warningMessage1, I18n::Message warningMessage2 = (I18n::Message) 0, bool specialExitKeys = false); - const Container * container() const; uint8_t m_magic; // Poor man's RTTI virtual void didBecomeActive(Window * window); @@ -69,7 +68,6 @@ protected: App(Container * container, Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0); ModalViewController m_modalViewController; private: - Container * m_container; Responder * m_firstResponder; Snapshot * m_snapshot; WarningController m_warningController; diff --git a/escher/src/app.cpp b/escher/src/app.cpp index db8d49626..dc96149c1 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -33,7 +33,6 @@ App::App(Container * container, Snapshot * snapshot, ViewController * rootViewCo Responder(nullptr), m_magic(Magic), m_modalViewController(this, rootViewController), - m_container(container), m_firstResponder(nullptr), m_snapshot(snapshot), m_warningController(this, warningMessage) @@ -101,10 +100,6 @@ void App::displayWarning(I18n::Message warningMessage1, I18n::Message warningMes displayModalViewController(&m_warningController, 0.5f, 0.5f); } -const Container * App::container() const { - return m_container; -} - void App::didBecomeActive(Window * window) { View * view = m_modalViewController.view(); assert(m_modalViewController.app() == this); From 2c98a6ea0d3233542994d53fc6dfbd73b80dce88 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 14 May 2019 17:13:35 +0200 Subject: [PATCH 042/111] [apps/home/controller] Substitute m_container by AppsContainer::sharedAppsContainer() --- apps/home/app.cpp | 3 +-- apps/home/controller.cpp | 21 ++++++++++++--------- apps/home/controller.h | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/apps/home/app.cpp b/apps/home/app.cpp index b7fa2ff0b..1fbbd39df 100644 --- a/apps/home/app.cpp +++ b/apps/home/app.cpp @@ -1,6 +1,5 @@ #include "app.h" #include -#include "../apps_container.h" extern "C" { #include @@ -27,7 +26,7 @@ App::Descriptor * App::Snapshot::descriptor() { App::App(Container * container, Snapshot * snapshot) : ::App(container, snapshot, &m_controller, I18n::Message::Warning), - m_controller(&m_modalViewController, (AppsContainer *)container, snapshot) + m_controller(&m_modalViewController, snapshot) { } diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index f177204ec..e4ca4b43e 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -47,9 +47,8 @@ void Controller::ContentView::layoutSubviews() { m_selectableTableView.setFrame(bounds()); } -Controller::Controller(Responder * parentResponder, ::AppsContainer * container, SelectableTableViewDataSource * selectionDataSource) : +Controller::Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource) : ViewController(parentResponder), - m_container(container), m_view(this, selectionDataSource), m_selectionDataSource(selectionDataSource) { @@ -57,7 +56,8 @@ Controller::Controller(Responder * parentResponder, ::AppsContainer * container, bool Controller::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { - bool switched = m_container->switchTo(m_container->appSnapshotAtIndex(m_selectionDataSource->selectedRow()*k_numberOfColumns+m_selectionDataSource->selectedColumn()+1)); + AppsContainer * container = AppsContainer::sharedAppsContainer(); + bool switched = container->switchTo(container->appSnapshotAtIndex(m_selectionDataSource->selectedRow()*k_numberOfColumns+m_selectionDataSource->selectedColumn()+1)); assert(switched); (void) switched; // Silence compilation warning about unused variable. return true; @@ -119,22 +119,25 @@ int Controller::reusableCellCount() { void Controller::willDisplayCellAtLocation(HighlightCell * cell, int i, int j) { AppCell * appCell = (AppCell *)cell; + AppsContainer * container = AppsContainer::sharedAppsContainer(); int appIndex = (j*k_numberOfColumns+i)+1; - if (appIndex >= m_container->numberOfApps()) { + if (appIndex >= container->numberOfApps()) { appCell->setVisible(false); } else { appCell->setVisible(true); - ::App::Descriptor * descriptor = m_container->appSnapshotAtIndex(appIndex)->descriptor(); + ::App::Descriptor * descriptor = container->appSnapshotAtIndex(appIndex)->descriptor(); appCell->setAppDescriptor(descriptor); } } int Controller::numberOfIcons() { - assert(m_container->numberOfApps() > 0); - return m_container->numberOfApps() - 1; + AppsContainer * container = AppsContainer::sharedAppsContainer(); + assert(container->numberOfApps() > 0); + return container->numberOfApps() - 1; } void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) { + AppsContainer * container = AppsContainer::sharedAppsContainer(); if (withinTemporarySelection) { return; } @@ -147,7 +150,7 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo * background complete redrawing but the code is a bit * clumsy. */ if (t->selectedRow() == numberOfRows()-1) { - m_view.reloadBottomRow(this, m_container->numberOfApps()-1, k_numberOfColumns); + m_view.reloadBottomRow(this, container->numberOfApps()-1, k_numberOfColumns); } /* To prevent the selectable table view to select cells that are unvisible, * we reselect the previous selected cell as soon as the selected cell is @@ -155,7 +158,7 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo * stay on a unvisible cell and to initialize the first cell on a visible one * (so the previous one is always visible). */ int appIndex = (t->selectedColumn()+t->selectedRow()*k_numberOfColumns)+1; - if (appIndex >= m_container->numberOfApps()) { + if (appIndex >= container->numberOfApps()) { t->selectCellAtLocation(previousSelectedCellX, previousSelectedCellY); } } diff --git a/apps/home/controller.h b/apps/home/controller.h index 116b6291a..d31fd4632 100644 --- a/apps/home/controller.h +++ b/apps/home/controller.h @@ -10,7 +10,7 @@ namespace Home { class Controller : public ViewController, public SimpleTableViewDataSource, public SelectableTableViewDelegate { public: - Controller(Responder * parentResponder, ::AppsContainer * container, SelectableTableViewDataSource * selectionDataSource); + Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource); View * view() override; @@ -40,7 +40,6 @@ private: void layoutSubviews() override; SelectableTableView m_selectableTableView; }; - AppsContainer * m_container; static constexpr KDCoordinate k_sideMargin = 4; static constexpr KDCoordinate k_bottomMargin = 14; static constexpr KDCoordinate k_indicatorMargin = 61; From 1f068199742d2a3ef9620c09c959430e60ec3e16 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 16 May 2019 14:54:16 +0200 Subject: [PATCH 043/111] [apps] Remove Container * parameter from all App constructors --- apps/calculation/app.cpp | 6 +++--- apps/calculation/app.h | 2 +- apps/code/app.cpp | 6 +++--- apps/code/app.h | 2 +- apps/graph/app.cpp | 6 +++--- apps/graph/app.h | 2 +- apps/hardware_test/app.cpp | 6 +++--- apps/hardware_test/app.h | 2 +- apps/home/app.cpp | 6 +++--- apps/home/app.h | 2 +- apps/on_boarding/app.cpp | 6 +++--- apps/on_boarding/app.h | 2 +- apps/probability/app.cpp | 6 +++--- apps/probability/app.h | 2 +- apps/regression/app.cpp | 6 +++--- apps/regression/app.h | 2 +- apps/sequence/app.cpp | 8 ++++---- apps/sequence/app.h | 2 +- apps/settings/app.cpp | 6 +++--- apps/settings/app.h | 2 +- apps/shared/expression_field_delegate_app.cpp | 4 ++-- apps/shared/expression_field_delegate_app.h | 2 +- apps/shared/function_app.h | 4 ++-- apps/shared/input_event_handler_delegate_app.cpp | 4 ++-- apps/shared/input_event_handler_delegate_app.h | 2 +- apps/shared/text_field_delegate_app.cpp | 4 ++-- apps/shared/text_field_delegate_app.h | 2 +- apps/solver/app.cpp | 6 +++--- apps/solver/app.h | 2 +- apps/statistics/app.cpp | 6 +++--- apps/statistics/app.h | 2 +- apps/usb/app.cpp | 6 +++--- apps/usb/app.h | 2 +- escher/include/escher/app.h | 2 +- escher/src/app.cpp | 2 +- 35 files changed, 66 insertions(+), 66 deletions(-) diff --git a/apps/calculation/app.cpp b/apps/calculation/app.cpp index 44c2a938e..fc09d13a8 100644 --- a/apps/calculation/app.cpp +++ b/apps/calculation/app.cpp @@ -23,7 +23,7 @@ const Image * App::Descriptor::icon() { } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } void App::Snapshot::reset() { @@ -39,8 +39,8 @@ void App::Snapshot::tidy() { m_calculationStore.tidy(); } -App::App(Container * container, Snapshot * snapshot) : - ExpressionFieldDelegateApp(container, snapshot, &m_editExpressionController), +App::App(Snapshot * snapshot) : + ExpressionFieldDelegateApp(snapshot, &m_editExpressionController), m_historyController(&m_editExpressionController, snapshot->calculationStore()), m_editExpressionController(&m_modalViewController, this, &m_historyController, snapshot->calculationStore()) { diff --git a/apps/calculation/app.h b/apps/calculation/app.h index 3379d5c68..62410ffee 100644 --- a/apps/calculation/app.h +++ b/apps/calculation/app.h @@ -34,7 +34,7 @@ public: bool storeExpressionAllowed() const override { return true; } char XNT() override; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); HistoryController m_historyController; EditExpressionController m_editExpressionController; }; diff --git a/apps/code/app.cpp b/apps/code/app.cpp index a640ded5a..e97f72a76 100644 --- a/apps/code/app.cpp +++ b/apps/code/app.cpp @@ -28,7 +28,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -72,8 +72,8 @@ void App::Snapshot::setOpt(const char * name, char * value) { } #endif -App::App(Container * container, Snapshot * snapshot) : - Shared::InputEventHandlerDelegateApp(container, snapshot, &m_codeStackViewController), +App::App(Snapshot * snapshot) : + Shared::InputEventHandlerDelegateApp(snapshot, &m_codeStackViewController), m_pythonHeap{}, m_pythonUser(nullptr), m_consoleController(nullptr, this, snapshot->scriptStore() diff --git a/apps/code/app.h b/apps/code/app.h index db1c0bfc6..2c215d26a 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -75,7 +75,7 @@ private: char m_pythonHeap[k_pythonHeapSize]; const void * m_pythonUser; - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); ConsoleController m_consoleController; ButtonRowController m_listFooter; MenuController m_menuController; diff --git a/apps/graph/app.cpp b/apps/graph/app.cpp index 1c35a84f0..36ad09e55 100644 --- a/apps/graph/app.cpp +++ b/apps/graph/app.cpp @@ -28,7 +28,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -49,8 +49,8 @@ void App::Snapshot::tidy() { m_graphRange.setDelegate(nullptr); } -App::App(Container * container, Snapshot * snapshot) : - FunctionApp(container, snapshot, &m_inputViewController), +App::App(Snapshot * snapshot) : + FunctionApp(snapshot, &m_inputViewController), m_listController(&m_listFooter, &m_listHeader, &m_listFooter), m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey), m_listHeader(&m_listStackViewController, &m_listFooter, &m_listController), diff --git a/apps/graph/app.h b/apps/graph/app.h index 795820047..1a7fdbf6a 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -35,7 +35,7 @@ public: NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; CartesianFunctionStore * functionStore() override { return static_cast(Shared::FunctionApp::functionStore()); } private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); ListController m_listController; ButtonRowController m_listFooter; ButtonRowController m_listHeader; diff --git a/apps/hardware_test/app.cpp b/apps/hardware_test/app.cpp index ce18a656c..57810c0b4 100644 --- a/apps/hardware_test/app.cpp +++ b/apps/hardware_test/app.cpp @@ -8,7 +8,7 @@ extern "C" { namespace HardwareTest { App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -16,8 +16,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - ::App(container, snapshot, &m_wizardViewController), +App::App(Snapshot * snapshot) : + ::App(snapshot, &m_wizardViewController), m_wizardViewController(&m_modalViewController) { } diff --git a/apps/hardware_test/app.h b/apps/hardware_test/app.h index 6d5047ffc..ac789f0ae 100644 --- a/apps/hardware_test/app.h +++ b/apps/hardware_test/app.h @@ -34,7 +34,7 @@ private: SerialNumberController m_serialNumberController; }; - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); WizardViewController m_wizardViewController; }; diff --git a/apps/home/app.cpp b/apps/home/app.cpp index 1fbbd39df..5c5cc8f9c 100644 --- a/apps/home/app.cpp +++ b/apps/home/app.cpp @@ -16,7 +16,7 @@ I18n::Message App::Descriptor::upperName() { } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -24,8 +24,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - ::App(container, snapshot, &m_controller, I18n::Message::Warning), +App::App(Snapshot * snapshot) : + ::App(snapshot, &m_controller, I18n::Message::Warning), m_controller(&m_modalViewController, snapshot) { } diff --git a/apps/home/app.h b/apps/home/app.h index a23c2d19b..9e89696e9 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -21,7 +21,7 @@ public: Descriptor * descriptor() override; }; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); Controller m_controller; }; diff --git a/apps/on_boarding/app.cpp b/apps/on_boarding/app.cpp index 1854f48e0..258f7be2a 100644 --- a/apps/on_boarding/app.cpp +++ b/apps/on_boarding/app.cpp @@ -4,7 +4,7 @@ namespace OnBoarding { App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -12,8 +12,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - ::App(container, snapshot, &m_languageController), +App::App(Snapshot * snapshot) : + ::App(snapshot, &m_languageController), m_languageController(&m_modalViewController, &m_logoController), m_logoController() { diff --git a/apps/on_boarding/app.h b/apps/on_boarding/app.h index 11de77f28..dc8665656 100644 --- a/apps/on_boarding/app.h +++ b/apps/on_boarding/app.h @@ -19,7 +19,7 @@ public: bool processEvent(Ion::Events::Event) override; void didBecomeActive(Window * window) override; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); LanguageController m_languageController; LogoController m_logoController; }; diff --git a/apps/probability/app.cpp b/apps/probability/app.cpp index ae2e2f693..cda4348d5 100644 --- a/apps/probability/app.cpp +++ b/apps/probability/app.cpp @@ -35,7 +35,7 @@ App::Snapshot::~Snapshot() { } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -67,8 +67,8 @@ App::Snapshot::Page App::Snapshot::activePage() { return m_activePage; } -App::App(Container * container, Snapshot * snapshot) : - TextFieldDelegateApp(container, snapshot, &m_stackViewController), +App::App(Snapshot * snapshot) : + TextFieldDelegateApp(snapshot, &m_stackViewController), m_calculationController(&m_stackViewController, this, snapshot->law(), snapshot->calculation()), m_parametersController(&m_stackViewController, this, snapshot->law(), &m_calculationController), m_lawController(&m_stackViewController, snapshot->law(), &m_parametersController), diff --git a/apps/probability/app.h b/apps/probability/app.h index afbfe0fe1..12d1f3bdf 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -55,7 +55,7 @@ public: Page m_activePage; }; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); CalculationController m_calculationController; ParametersController m_parametersController; LawController m_lawController; diff --git a/apps/regression/app.cpp b/apps/regression/app.cpp index afd5f27e9..37d6b2c27 100644 --- a/apps/regression/app.cpp +++ b/apps/regression/app.cpp @@ -29,7 +29,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } void App::Snapshot::reset() { @@ -50,8 +50,8 @@ void App::Snapshot::tidy() { m_store.tidy(); } -App::App(Container * container, Snapshot * snapshot) : - TextFieldDelegateApp(container, snapshot, &m_tabViewController), +App::App(Snapshot * snapshot) : + TextFieldDelegateApp(snapshot, &m_tabViewController), m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()), m_calculationAlternateEmptyViewController(&m_calculationHeader, &m_calculationController, &m_calculationController), m_calculationHeader(&m_tabViewController, &m_calculationAlternateEmptyViewController, &m_calculationController), diff --git a/apps/regression/app.h b/apps/regression/app.h index f32116243..f19a4d113 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -42,7 +42,7 @@ public: }; RegressionController * regressionController() { return &m_regressionController; } private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); CalculationController m_calculationController; AlternateEmptyViewController m_calculationAlternateEmptyViewController; ButtonRowController m_calculationHeader; diff --git a/apps/sequence/app.cpp b/apps/sequence/app.cpp index b40a26c19..f6930fb4b 100644 --- a/apps/sequence/app.cpp +++ b/apps/sequence/app.cpp @@ -26,7 +26,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } void App::Snapshot::reset() { @@ -53,9 +53,9 @@ void App::Snapshot::tidy() { m_graphRange.setDelegate(nullptr); } -App::App(Container * container, Snapshot * snapshot) : - FunctionApp(container, snapshot, &m_inputViewController), - m_sequenceContext(((AppsContainer *)container)->globalContext(), snapshot->functionStore()), +App::App(Snapshot * snapshot) : + FunctionApp(snapshot, &m_inputViewController), + m_sequenceContext(AppsContainer::sharedAppsContainer()->globalContext(), snapshot->functionStore()), m_listController(&m_listFooter, this, &m_listHeader, &m_listFooter), m_listFooter(&m_listHeader, &m_listController, &m_listController, ButtonRowController::Position::Bottom, ButtonRowController::Style::EmbossedGrey), m_listHeader(nullptr, &m_listFooter, &m_listController), diff --git a/apps/sequence/app.h b/apps/sequence/app.h index f514839e8..02c215f77 100644 --- a/apps/sequence/app.h +++ b/apps/sequence/app.h @@ -40,7 +40,7 @@ public: SequenceContext * localContext() override; SequenceStore * functionStore() override { return static_cast(Shared::FunctionApp::functionStore()); } private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); SequenceContext m_sequenceContext; ListController m_listController; ButtonRowController m_listFooter; diff --git a/apps/settings/app.cpp b/apps/settings/app.cpp index d096c3d90..36bb89d00 100644 --- a/apps/settings/app.cpp +++ b/apps/settings/app.cpp @@ -17,7 +17,7 @@ const Image * App::Descriptor::icon() { } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -25,8 +25,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - Shared::TextFieldDelegateApp(container, snapshot, &m_stackViewController), +App::App(Snapshot * snapshot) : + Shared::TextFieldDelegateApp(snapshot, &m_stackViewController), m_mainController(&m_stackViewController, this), m_stackViewController(&m_modalViewController, &m_mainController) { diff --git a/apps/settings/app.h b/apps/settings/app.h index a84c79b16..3f4c064d0 100644 --- a/apps/settings/app.h +++ b/apps/settings/app.h @@ -20,7 +20,7 @@ public: Descriptor * descriptor() override; }; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); MainController m_mainController; StackViewController m_stackViewController; }; diff --git a/apps/shared/expression_field_delegate_app.cpp b/apps/shared/expression_field_delegate_app.cpp index 95dd683bf..f2e386778 100644 --- a/apps/shared/expression_field_delegate_app.cpp +++ b/apps/shared/expression_field_delegate_app.cpp @@ -7,8 +7,8 @@ using namespace Poincare; namespace Shared { -ExpressionFieldDelegateApp::ExpressionFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) : - TextFieldDelegateApp(container, snapshot, rootViewController), +ExpressionFieldDelegateApp::ExpressionFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController) : + TextFieldDelegateApp(snapshot, rootViewController), LayoutFieldDelegate() { } diff --git a/apps/shared/expression_field_delegate_app.h b/apps/shared/expression_field_delegate_app.h index 348e31050..1c73f1c7e 100644 --- a/apps/shared/expression_field_delegate_app.h +++ b/apps/shared/expression_field_delegate_app.h @@ -12,7 +12,7 @@ public: bool layoutFieldShouldFinishEditing(LayoutField * layoutField, Ion::Events::Event event) override; virtual bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override; protected: - ExpressionFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController); + ExpressionFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController); }; } diff --git a/apps/shared/function_app.h b/apps/shared/function_app.h index 421e74f0f..86300c8f5 100644 --- a/apps/shared/function_app.h +++ b/apps/shared/function_app.h @@ -39,8 +39,8 @@ public: void willBecomeInactive() override; protected: - FunctionApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) : - ExpressionFieldDelegateApp(container, snapshot, rootViewController) + FunctionApp(Snapshot * snapshot, ViewController * rootViewController) : + ExpressionFieldDelegateApp(snapshot, rootViewController) {} // TextFieldDelegateApp bool isAcceptableExpression(const Poincare::Expression expression) override; diff --git a/apps/shared/input_event_handler_delegate_app.cpp b/apps/shared/input_event_handler_delegate_app.cpp index 5da50cbf1..cc9b5d525 100644 --- a/apps/shared/input_event_handler_delegate_app.cpp +++ b/apps/shared/input_event_handler_delegate_app.cpp @@ -7,8 +7,8 @@ using namespace Poincare; namespace Shared { -InputEventHandlerDelegateApp::InputEventHandlerDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) : - ::App(container, snapshot, rootViewController, I18n::Message::Warning), +InputEventHandlerDelegateApp::InputEventHandlerDelegateApp(Snapshot * snapshot, ViewController * rootViewController) : + ::App(snapshot, rootViewController, I18n::Message::Warning), InputEventHandlerDelegate() { } diff --git a/apps/shared/input_event_handler_delegate_app.h b/apps/shared/input_event_handler_delegate_app.h index f037aaa18..e869383b1 100644 --- a/apps/shared/input_event_handler_delegate_app.h +++ b/apps/shared/input_event_handler_delegate_app.h @@ -13,7 +13,7 @@ public: Toolbox * toolboxForInputEventHandler(InputEventHandler * textInput) override; NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; protected: - InputEventHandlerDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController); + InputEventHandlerDelegateApp(Snapshot * snapshot, ViewController * rootViewController); }; } diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index b073f5739..ad6addf9c 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -52,8 +52,8 @@ bool TextFieldDelegateApp::hasUndefinedValue(const char * text, double & value) /* Protected */ -TextFieldDelegateApp::TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController) : - InputEventHandlerDelegateApp(container, snapshot, rootViewController), +TextFieldDelegateApp::TextFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController) : + InputEventHandlerDelegateApp(snapshot, rootViewController), TextFieldDelegate() { } diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index 74885ad69..c7d1fa7e2 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -20,7 +20,7 @@ public: bool isAcceptableText(const char * text); bool hasUndefinedValue(const char * text, double & value); protected: - TextFieldDelegateApp(Container * container, Snapshot * snapshot, ViewController * rootViewController); + TextFieldDelegateApp(Snapshot * snapshot, ViewController * rootViewController); bool fieldDidReceiveEvent(EditableField * field, Responder * responder, Ion::Events::Event event); bool isFinishingEvent(Ion::Events::Event event); virtual bool isAcceptableExpression(const Poincare::Expression expression); diff --git a/apps/solver/app.cpp b/apps/solver/app.cpp index a27ad587e..4e17ef5e3 100644 --- a/apps/solver/app.cpp +++ b/apps/solver/app.cpp @@ -24,7 +24,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -42,8 +42,8 @@ void App::Snapshot::tidy() { m_equationStore.tidy(); } -App::App(Container * container, Snapshot * snapshot) : - ExpressionFieldDelegateApp(container, snapshot, &m_inputViewController), +App::App(Snapshot * snapshot) : + ExpressionFieldDelegateApp(snapshot, &m_inputViewController), m_solutionsController(&m_alternateEmptyViewController, snapshot->equationStore()), m_intervalController(nullptr, this, snapshot->equationStore()), m_alternateEmptyViewController(nullptr, &m_solutionsController, &m_solutionsController), diff --git a/apps/solver/app.h b/apps/solver/app.h index 048871cfd..d9c8cae6a 100644 --- a/apps/solver/app.h +++ b/apps/solver/app.h @@ -35,7 +35,7 @@ public: void willBecomeInactive() override; char XNT() override; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); SolutionsController m_solutionsController; IntervalController m_intervalController; AlternateEmptyViewController m_alternateEmptyViewController; diff --git a/apps/statistics/app.cpp b/apps/statistics/app.cpp index 787e51ace..f93912273 100644 --- a/apps/statistics/app.cpp +++ b/apps/statistics/app.cpp @@ -31,7 +31,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } void App::Snapshot::reset() { @@ -49,8 +49,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - TextFieldDelegateApp(container, snapshot, &m_tabViewController), +App::App(Snapshot * snapshot) : + TextFieldDelegateApp(snapshot, &m_tabViewController), m_calculationController(&m_calculationAlternateEmptyViewController, &m_calculationHeader, snapshot->store()), m_calculationAlternateEmptyViewController(&m_calculationHeader, &m_calculationController, &m_calculationController), m_calculationHeader(&m_tabViewController, &m_calculationAlternateEmptyViewController, &m_calculationController), diff --git a/apps/statistics/app.h b/apps/statistics/app.h index 06871fae4..f39a086d2 100644 --- a/apps/statistics/app.h +++ b/apps/statistics/app.h @@ -44,7 +44,7 @@ public: BoxView::Quantile m_selectedBoxQuantile; }; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); CalculationController m_calculationController; AlternateEmptyViewController m_calculationAlternateEmptyViewController; ButtonRowController m_calculationHeader; diff --git a/apps/usb/app.cpp b/apps/usb/app.cpp index 7de9e909a..ec0125f9b 100644 --- a/apps/usb/app.cpp +++ b/apps/usb/app.cpp @@ -13,7 +13,7 @@ I18n::Message App::Descriptor::upperName() { } App * App::Snapshot::unpack(Container * container) { - return new (container->currentAppBuffer()) App(container, this); + return new (container->currentAppBuffer()) App(this); } App::Descriptor * App::Snapshot::descriptor() { @@ -21,8 +21,8 @@ App::Descriptor * App::Snapshot::descriptor() { return &descriptor; } -App::App(Container * container, Snapshot * snapshot) : - ::App(container, snapshot, &m_usbConnectedController) +App::App(Snapshot * snapshot) : + ::App(snapshot, &m_usbConnectedController) { } diff --git a/apps/usb/app.h b/apps/usb/app.h index a4670fe47..356cf36f1 100644 --- a/apps/usb/app.h +++ b/apps/usb/app.h @@ -20,7 +20,7 @@ public: }; bool processEvent(Ion::Events::Event) override; private: - App(Container * container, Snapshot * snapshot); + App(Snapshot * snapshot); USBConnectedController m_usbConnectedController; }; diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index bc83f12c0..6d26a60b4 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -65,7 +65,7 @@ public: virtual int numberOfTimers(); virtual Timer * timerAtIndex(int i); protected: - App(Container * container, Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0); + App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage = (I18n::Message)0); ModalViewController m_modalViewController; private: Responder * m_firstResponder; diff --git a/escher/src/app.cpp b/escher/src/app.cpp index dc96149c1..6d2d2f9b8 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -29,7 +29,7 @@ void App::Snapshot::reset() { void App::Snapshot::tidy() { } -App::App(Container * container, Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage) : +App::App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage) : Responder(nullptr), m_magic(Magic), m_modalViewController(this, rootViewController), From 443f974cbb74dfb9d5d18be189278ccf85bba501 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Mon, 3 Jun 2019 10:32:25 +0200 Subject: [PATCH 044/111] [escher/container] Inline activeApp() accessor --- escher/include/escher/container.h | 2 +- escher/src/container.cpp | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 4111aaa2b..0f929d8a9 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -29,7 +29,7 @@ public: Container& operator=(Container&& other) = delete; virtual void * currentAppBuffer() = 0; virtual void run(); - App * activeApp(); + App * activeApp() { return m_activeApp; } virtual bool dispatchEvent(Ion::Events::Event event) override; virtual bool switchTo(App::Snapshot * snapshot); protected: diff --git a/escher/src/container.cpp b/escher/src/container.cpp index 0bf23e636..5bed9f494 100644 --- a/escher/src/container.cpp +++ b/escher/src/container.cpp @@ -40,10 +40,6 @@ bool Container::switchTo(App::Snapshot * snapshot) { return true; } -App * Container::activeApp() { - return m_activeApp; -} - bool Container::dispatchEvent(Ion::Events::Event event) { if (event == Ion::Events::TimerFire ) { window()->redraw(); From ba2a98f5e5acd025323872891ee7c2653b2538cb Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 16 May 2019 17:30:45 +0200 Subject: [PATCH 045/111] [escher/app] Remove poor man's RTTI --- escher/include/escher/app.h | 2 -- escher/src/app.cpp | 1 - escher/src/responder.cpp | 4 ---- 3 files changed, 7 deletions(-) diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index 6d26a60b4..5a0ebfb91 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -45,7 +45,6 @@ public: /* The destructor has to be virtual. Otherwise calling a destructor on an * App * pointing to a Derived App would have undefined behaviour. */ virtual ~App() = default; - constexpr static uint8_t Magic = 0xA8; Snapshot * snapshot(); void setFirstResponder(Responder * responder); Responder * firstResponder(); @@ -57,7 +56,6 @@ public: KDCoordinate topMargin = 0, KDCoordinate leftMargin = 0, KDCoordinate bottomMargin = 0, KDCoordinate rightMargin = 0); void dismissModalViewController(); void displayWarning(I18n::Message warningMessage1, I18n::Message warningMessage2 = (I18n::Message) 0, bool specialExitKeys = false); - uint8_t m_magic; // Poor man's RTTI virtual void didBecomeActive(Window * window); virtual void willBecomeInactive(); diff --git a/escher/src/app.cpp b/escher/src/app.cpp index 6d2d2f9b8..4475051d5 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -31,7 +31,6 @@ void App::Snapshot::tidy() { App::App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message warningMessage) : Responder(nullptr), - m_magic(Magic), m_modalViewController(this, rootViewController), m_firstResponder(nullptr), m_snapshot(snapshot), diff --git a/escher/src/responder.cpp b/escher/src/responder.cpp index 919b6d99d..97616d02d 100644 --- a/escher/src/responder.cpp +++ b/escher/src/responder.cpp @@ -69,10 +69,6 @@ App * Responder::app() const { while (rootResponder->parentResponder() != nullptr) { rootResponder = rootResponder->parentResponder(); } - /* If we used RTTI we could use a dynamic_cast, which would be a lot more - * safe, as such: - * return dynamic_cast(rootResponder); */ App * result = (App *)rootResponder; - assert(result->m_magic == App::Magic); // Poor man's RTTI return result; } From 652cbae9acb71e8312e8f9a67836df601911794a Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 16 May 2019 17:42:15 +0200 Subject: [PATCH 046/111] [escher/responder] Access the app directly from the shared container --- escher/src/responder.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/escher/src/responder.cpp b/escher/src/responder.cpp index 97616d02d..85fef4a17 100644 --- a/escher/src/responder.cpp +++ b/escher/src/responder.cpp @@ -1,6 +1,5 @@ #include -#include -#include +#include #include Responder::Responder(Responder * parentResponder) : @@ -63,12 +62,6 @@ Responder * Responder::commonAncestorWith(Responder * responder) { return s; } -/* We assume the app is the root parent. */ App * Responder::app() const { - const Responder * rootResponder = this; - while (rootResponder->parentResponder() != nullptr) { - rootResponder = rootResponder->parentResponder(); - } - App * result = (App *)rootResponder; - return result; + return Container::sharedContainer()->activeApp(); } From 55487678097ef5c063eaae85077de830fcf427b4 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 17 May 2019 10:50:53 +0200 Subject: [PATCH 047/111] [apps] Timers access the shared container directly --- apps/apps_container.cpp | 4 ++-- apps/battery_timer.cpp | 10 +++++----- apps/battery_timer.h | 5 +---- apps/suspend_timer.cpp | 10 +++++----- apps/suspend_timer.h | 5 +---- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index ce1a9135a..76ca26097 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -64,8 +64,8 @@ AppsContainer::AppsContainer() : #elif EPSILON_BOOT_PROMPT == EPSILON_UPDATE_PROMPT m_promptController(sPromptMessages, sPromptColors, 6), #endif - m_batteryTimer(BatteryTimer(this)), - m_suspendTimer(SuspendTimer(this)), + m_batteryTimer(), + m_suspendTimer(), m_backlightDimmingTimer(), m_homeSnapshot(), m_onBoardingSnapshot(), diff --git a/apps/battery_timer.cpp b/apps/battery_timer.cpp index ced5c1896..db53d7c90 100644 --- a/apps/battery_timer.cpp +++ b/apps/battery_timer.cpp @@ -1,16 +1,16 @@ #include "battery_timer.h" #include "apps_container.h" -BatteryTimer::BatteryTimer(AppsContainer * container) : - Timer(1), - m_container(container) +BatteryTimer::BatteryTimer() : + Timer(1) { } bool BatteryTimer::fire() { - bool needRedrawing = m_container->updateBatteryState(); + AppsContainer * container = AppsContainer::sharedAppsContainer(); + bool needRedrawing = container->updateBatteryState(); if (Ion::Battery::level() == Ion::Battery::Charge::EMPTY) { - m_container->shutdownDueToLowBattery(); + container->shutdownDueToLowBattery(); } return needRedrawing; } diff --git a/apps/battery_timer.h b/apps/battery_timer.h index ccc7d0c46..90ad16c11 100644 --- a/apps/battery_timer.h +++ b/apps/battery_timer.h @@ -3,14 +3,11 @@ #include -class AppsContainer; - class BatteryTimer : public Timer { public: - BatteryTimer(AppsContainer * container); + BatteryTimer(); private: bool fire() override; - AppsContainer * m_container; }; #endif diff --git a/apps/suspend_timer.cpp b/apps/suspend_timer.cpp index 4984be1cf..34562d819 100644 --- a/apps/suspend_timer.cpp +++ b/apps/suspend_timer.cpp @@ -1,16 +1,16 @@ #include "suspend_timer.h" #include "apps_container.h" -SuspendTimer::SuspendTimer(AppsContainer * container) : - Timer(k_idleBeforeSuspendDuration/Timer::TickDuration), - m_container(container) +SuspendTimer::SuspendTimer() : + Timer(k_idleBeforeSuspendDuration/Timer::TickDuration) { } bool SuspendTimer::fire() { - /* We could just call m_container->suspend(), but we want to notify all + /* We could just call container->suspend(), but we want to notify all * responders in the responder chain that the calculator will be switched off, * so we use an event to switch off the calculator. */ - m_container->dispatchEvent(Ion::Events::OnOff); + AppsContainer * container = AppsContainer::sharedAppsContainer(); + container->dispatchEvent(Ion::Events::OnOff); return false; } diff --git a/apps/suspend_timer.h b/apps/suspend_timer.h index c63c97ad3..0a7b735d6 100644 --- a/apps/suspend_timer.h +++ b/apps/suspend_timer.h @@ -3,15 +3,12 @@ #include -class AppsContainer; - class SuspendTimer : public Timer { public: - SuspendTimer(AppsContainer * container); + SuspendTimer(); private: constexpr static int k_idleBeforeSuspendDuration = 5*60*1000; // In miliseconds bool fire() override; - AppsContainer * m_container; }; #endif From 62cec10b46f568fcb613f3e3533d5a30cdbc395d Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 17 May 2019 14:58:04 +0200 Subject: [PATCH 048/111] [apps] Clean unnecessary AppsContainer class declarations and header inclusions --- apps/calculation/app.cpp | 1 - apps/calculation/edit_expression_controller.cpp | 1 - apps/calculation/history_controller.cpp | 1 - apps/code/app.cpp | 1 - apps/hardware_test/app.cpp | 1 - apps/hardware_test/app.h | 2 -- apps/home/app.h | 2 -- apps/home/controller.h | 2 -- apps/probability/calculation_controller.cpp | 1 - apps/regression/store.cpp | 1 - apps/sequence/list/list_parameter_controller.cpp | 1 - apps/settings/sub_menu/about_controller.cpp | 3 --- apps/settings/sub_menu/generic_sub_controller.cpp | 2 -- apps/shared/editable_cell_table_view_controller.cpp | 1 - apps/shared/expression_field_delegate_app.cpp | 2 +- apps/shared/float_parameter_controller.cpp | 1 - apps/shared/function_app.cpp | 1 - apps/shared/function_app.h | 2 -- apps/shared/input_event_handler_delegate_app.h | 2 -- apps/shared/message_controller.cpp | 1 - apps/shared/range_parameter_controller.cpp | 2 -- apps/shared/sum_graph_controller.cpp | 1 - apps/shared/text_field_delegate_app.h | 2 -- apps/shared/values_controller.cpp | 2 -- apps/statistics/box_controller.cpp | 1 - apps/statistics/calculation_controller.cpp | 2 +- apps/statistics/histogram_controller.cpp | 1 - apps/usb/app.cpp | 2 +- 28 files changed, 3 insertions(+), 39 deletions(-) diff --git a/apps/calculation/app.cpp b/apps/calculation/app.cpp index fc09d13a8..5cb19d37d 100644 --- a/apps/calculation/app.cpp +++ b/apps/calculation/app.cpp @@ -1,5 +1,4 @@ #include "app.h" -#include "../apps_container.h" #include "calculation_icon.h" #include #include diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 116cf869f..3b30b042f 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -1,6 +1,5 @@ #include "edit_expression_controller.h" #include "app.h" -#include "../apps_container.h" #include #include #include diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 3b75f6ee6..71d193f39 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -1,6 +1,5 @@ #include "history_controller.h" #include "app.h" -#include "../apps_container.h" #include using namespace Shared; diff --git a/apps/code/app.cpp b/apps/code/app.cpp index e97f72a76..609ea672a 100644 --- a/apps/code/app.cpp +++ b/apps/code/app.cpp @@ -1,5 +1,4 @@ #include "app.h" -#include "../apps_container.h" #include "code_icon.h" #include #include "helpers.h" diff --git a/apps/hardware_test/app.cpp b/apps/hardware_test/app.cpp index 57810c0b4..6af62791a 100644 --- a/apps/hardware_test/app.cpp +++ b/apps/hardware_test/app.cpp @@ -1,5 +1,4 @@ #include "app.h" -#include "../apps_container.h" extern "C" { #include diff --git a/apps/hardware_test/app.h b/apps/hardware_test/app.h index ac789f0ae..de13e765f 100644 --- a/apps/hardware_test/app.h +++ b/apps/hardware_test/app.h @@ -8,8 +8,6 @@ #include "battery_test_controller.h" #include "serial_number_controller.h" -class AppsContainer; - namespace HardwareTest { class App : public ::App { diff --git a/apps/home/app.h b/apps/home/app.h index 9e89696e9..cdbf95b1b 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -4,8 +4,6 @@ #include #include "controller.h" -class AppsContainer; - namespace Home { class App : public ::App { diff --git a/apps/home/controller.h b/apps/home/controller.h index d31fd4632..a7762d433 100644 --- a/apps/home/controller.h +++ b/apps/home/controller.h @@ -4,8 +4,6 @@ #include #include "app_cell.h" -class AppsContainer; - namespace Home { class Controller : public ViewController, public SimpleTableViewDataSource, public SelectableTableViewDelegate { diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index e422a3884..007f938ab 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -1,6 +1,5 @@ #include "calculation_controller.h" #include "../constant.h" -#include "../apps_container.h" #include "../shared/poincare_helpers.h" #include "app.h" #include "calculation/discrete_calculation.h" diff --git a/apps/regression/store.cpp b/apps/regression/store.cpp index 7174cb8d3..120db5cea 100644 --- a/apps/regression/store.cpp +++ b/apps/regression/store.cpp @@ -1,6 +1,5 @@ #include "store.h" #include "linear_model_helper.h" -#include "apps/apps_container.h" #include #include #include diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 5674f4837..fac6aba66 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -1,7 +1,6 @@ #include "list_parameter_controller.h" #include "list_controller.h" #include "../app.h" -#include "../../apps_container.h" #include "../../shared/poincare_helpers.h" using namespace Poincare; diff --git a/apps/settings/sub_menu/about_controller.cpp b/apps/settings/sub_menu/about_controller.cpp index a8096d0de..1596f6e44 100644 --- a/apps/settings/sub_menu/about_controller.cpp +++ b/apps/settings/sub_menu/about_controller.cpp @@ -1,10 +1,7 @@ #include "about_controller.h" -#include "../../apps_container.h" #include #include -using namespace Shared; - namespace Settings { AboutController::AboutController(Responder * parentResponder) : diff --git a/apps/settings/sub_menu/generic_sub_controller.cpp b/apps/settings/sub_menu/generic_sub_controller.cpp index e70e3f747..80ff32d8b 100644 --- a/apps/settings/sub_menu/generic_sub_controller.cpp +++ b/apps/settings/sub_menu/generic_sub_controller.cpp @@ -1,10 +1,8 @@ #include "generic_sub_controller.h" -#include "../../apps_container.h" #include #include using namespace Poincare; -using namespace Shared; namespace Settings { diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index 03049a14c..abe82f111 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -1,5 +1,4 @@ #include "editable_cell_table_view_controller.h" -#include "../apps_container.h" #include "../shared/poincare_helpers.h" #include "../constant.h" #include "text_field_delegate_app.h" diff --git a/apps/shared/expression_field_delegate_app.cpp b/apps/shared/expression_field_delegate_app.cpp index f2e386778..6dab7a879 100644 --- a/apps/shared/expression_field_delegate_app.cpp +++ b/apps/shared/expression_field_delegate_app.cpp @@ -1,7 +1,7 @@ #include "expression_field_delegate_app.h" #include #include -#include "../apps_container.h" +#include using namespace Poincare; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 3f210dce1..1bdabcc6c 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -1,6 +1,5 @@ #include "float_parameter_controller.h" #include "../constant.h" -#include "../apps_container.h" #include "../shared/poincare_helpers.h" #include "text_field_delegate_app.h" #include diff --git a/apps/shared/function_app.cpp b/apps/shared/function_app.cpp index 58d3f9f3b..fea059c2d 100644 --- a/apps/shared/function_app.cpp +++ b/apps/shared/function_app.cpp @@ -1,5 +1,4 @@ #include "function_app.h" -#include "../apps_container.h" using namespace Poincare; diff --git a/apps/shared/function_app.h b/apps/shared/function_app.h index 86300c8f5..687e6185a 100644 --- a/apps/shared/function_app.h +++ b/apps/shared/function_app.h @@ -6,8 +6,6 @@ #include "curve_view_cursor.h" #include "interval.h" -class AppsContainer; - namespace Shared { class FunctionApp : public ExpressionFieldDelegateApp { diff --git a/apps/shared/input_event_handler_delegate_app.h b/apps/shared/input_event_handler_delegate_app.h index e869383b1..3f2927c9c 100644 --- a/apps/shared/input_event_handler_delegate_app.h +++ b/apps/shared/input_event_handler_delegate_app.h @@ -3,8 +3,6 @@ #include -class AppsContainer; - namespace Shared { class InputEventHandlerDelegateApp : public ::App, public InputEventHandlerDelegate { diff --git a/apps/shared/message_controller.cpp b/apps/shared/message_controller.cpp index 81521f96e..cab2151c5 100644 --- a/apps/shared/message_controller.cpp +++ b/apps/shared/message_controller.cpp @@ -1,5 +1,4 @@ #include "message_controller.h" -#include "../apps_container.h" MessageController::MessageController(I18n::Message * messages, KDColor * colors, uint8_t numberOfMessages) : ViewController(nullptr), diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index cae297599..4fb1806f1 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -1,6 +1,5 @@ #include "range_parameter_controller.h" #include "text_field_delegate_app.h" -#include "../apps_container.h" #include using namespace Poincare; @@ -124,4 +123,3 @@ int RangeParameterController::reusableParameterCellCount(int type) { } } - diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index 1c4f5b8e5..559809812 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -1,6 +1,5 @@ #include "sum_graph_controller.h" #include "function_app.h" -#include "../apps_container.h" #include #include #include diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index c7d1fa7e2..c9f96b29c 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -6,8 +6,6 @@ #include "input_event_handler_delegate_app.h" #include -class AppsContainer; - namespace Shared { class TextFieldDelegateApp : public InputEventHandlerDelegateApp, public TextFieldDelegate { diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index 542830b29..559faa97e 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -1,7 +1,6 @@ #include "values_controller.h" #include "function_app.h" #include "../constant.h" -#include "../apps_container.h" #include "poincare_helpers.h" #include @@ -342,4 +341,3 @@ FunctionStore * ValuesController::functionStore() const { } } - diff --git a/apps/statistics/box_controller.cpp b/apps/statistics/box_controller.cpp index 2e26b3565..54e6b30cb 100644 --- a/apps/statistics/box_controller.cpp +++ b/apps/statistics/box_controller.cpp @@ -1,7 +1,6 @@ #include "box_controller.h" #include "app.h" #include "../shared/poincare_helpers.h" -#include "../apps_container.h" using namespace Poincare; using namespace Shared; diff --git a/apps/statistics/calculation_controller.cpp b/apps/statistics/calculation_controller.cpp index 4a8e78062..1524d61c8 100644 --- a/apps/statistics/calculation_controller.cpp +++ b/apps/statistics/calculation_controller.cpp @@ -1,5 +1,5 @@ #include "calculation_controller.h" -#include "../apps_container.h" +#include #include "../shared/poincare_helpers.h" #include diff --git a/apps/statistics/histogram_controller.cpp b/apps/statistics/histogram_controller.cpp index 60b0e5338..1e5b9320c 100644 --- a/apps/statistics/histogram_controller.cpp +++ b/apps/statistics/histogram_controller.cpp @@ -1,5 +1,4 @@ #include "histogram_controller.h" -#include "../apps_container.h" #include "../shared/poincare_helpers.h" #include "../shared/text_helpers.h" #include "app.h" diff --git a/apps/usb/app.cpp b/apps/usb/app.cpp index ec0125f9b..99cdd7a6c 100644 --- a/apps/usb/app.cpp +++ b/apps/usb/app.cpp @@ -1,5 +1,5 @@ #include "app.h" -#include "../apps_container.h" +#include #include namespace USB { From 3aa2e5d6a7c1260e05a04714bc07102c70bb2d8f Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 29 May 2019 16:37:12 +0200 Subject: [PATCH 049/111] [apps/on_boarding] Move LanguageController::reinitOnBoarding() to App --- apps/on_boarding/app.cpp | 9 +++++++-- apps/on_boarding/app.h | 1 + apps/on_boarding/language_controller.cpp | 5 ----- apps/on_boarding/language_controller.h | 1 - 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/on_boarding/app.cpp b/apps/on_boarding/app.cpp index 258f7be2a..70a3f1e25 100644 --- a/apps/on_boarding/app.cpp +++ b/apps/on_boarding/app.cpp @@ -33,14 +33,19 @@ bool App::processEvent(Ion::Events::Event e) { return true; } if (e == Ion::Events::OnOff) { - m_languageController.reinitOnBoarding(); + reinitOnBoarding(); } return ::App::processEvent(e); } void App::didBecomeActive(Window * window) { ::App::didBecomeActive(window); - m_languageController.reinitOnBoarding(); + reinitOnBoarding(); +} + +void App::reinitOnBoarding() { + m_languageController.resetSelection(); + displayModalViewController(&m_logoController, 0.5f, 0.5f); } } diff --git a/apps/on_boarding/app.h b/apps/on_boarding/app.h index dc8665656..24a600343 100644 --- a/apps/on_boarding/app.h +++ b/apps/on_boarding/app.h @@ -20,6 +20,7 @@ public: void didBecomeActive(Window * window) override; private: App(Snapshot * snapshot); + void reinitOnBoarding(); LanguageController m_languageController; LogoController m_logoController; }; diff --git a/apps/on_boarding/language_controller.cpp b/apps/on_boarding/language_controller.cpp index b9326cbf1..d45aa0271 100644 --- a/apps/on_boarding/language_controller.cpp +++ b/apps/on_boarding/language_controller.cpp @@ -10,11 +10,6 @@ LanguageController::LanguageController(Responder * parentResponder, LogoControll { } -void LanguageController::reinitOnBoarding() { - resetSelection(); - app()->displayModalViewController(m_logoController, 0.5f, 0.5f); -} - bool LanguageController::handleEvent(Ion::Events::Event event) { if (Shared::LanguageController::handleEvent(event)) { AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); diff --git a/apps/on_boarding/language_controller.h b/apps/on_boarding/language_controller.h index cb838edc5..6fc6ef71b 100644 --- a/apps/on_boarding/language_controller.h +++ b/apps/on_boarding/language_controller.h @@ -10,7 +10,6 @@ namespace OnBoarding { class LanguageController : public Shared::LanguageController { public: LanguageController(Responder * parentResponder, LogoController * logoController); - void reinitOnBoarding(); bool handleEvent(Ion::Events::Event event) override; private: LogoController * m_logoController; From 154baae6d3d7ff97fc8f25639b43328347e85e65 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 29 May 2019 16:39:23 +0200 Subject: [PATCH 050/111] [apps/on_boarding] LanguageController does not need to hold LogoController --- apps/on_boarding/app.cpp | 2 +- apps/on_boarding/language_controller.cpp | 5 ++--- apps/on_boarding/language_controller.h | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/apps/on_boarding/app.cpp b/apps/on_boarding/app.cpp index 70a3f1e25..eae549004 100644 --- a/apps/on_boarding/app.cpp +++ b/apps/on_boarding/app.cpp @@ -14,7 +14,7 @@ App::Descriptor * App::Snapshot::descriptor() { App::App(Snapshot * snapshot) : ::App(snapshot, &m_languageController), - m_languageController(&m_modalViewController, &m_logoController), + m_languageController(&m_modalViewController), m_logoController() { } diff --git a/apps/on_boarding/language_controller.cpp b/apps/on_boarding/language_controller.cpp index d45aa0271..6e76bae4b 100644 --- a/apps/on_boarding/language_controller.cpp +++ b/apps/on_boarding/language_controller.cpp @@ -4,9 +4,8 @@ namespace OnBoarding { -LanguageController::LanguageController(Responder * parentResponder, LogoController * logoController) : - Shared::LanguageController(parentResponder, (Ion::Display::Height - I18n::NumberOfLanguages*Metric::ParameterCellHeight)/2), - m_logoController(logoController) +LanguageController::LanguageController(Responder * parentResponder) : + Shared::LanguageController(parentResponder, (Ion::Display::Height - I18n::NumberOfLanguages*Metric::ParameterCellHeight)/2) { } diff --git a/apps/on_boarding/language_controller.h b/apps/on_boarding/language_controller.h index 6fc6ef71b..10ab2c995 100644 --- a/apps/on_boarding/language_controller.h +++ b/apps/on_boarding/language_controller.h @@ -9,10 +9,8 @@ namespace OnBoarding { class LanguageController : public Shared::LanguageController { public: - LanguageController(Responder * parentResponder, LogoController * logoController); + LanguageController(Responder * parentResponder); bool handleEvent(Ion::Events::Event event) override; -private: - LogoController * m_logoController; }; } From 45875dd64269d3bf537950c407904924c5796e7a Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 3 Jun 2019 14:32:41 +0200 Subject: [PATCH 051/111] [escher] Make app() a global function This way it can easily be reached by anyone, including non-responders. And it can easily be overwritten in namespaced apps. --- apps/code/console_controller.cpp | 2 +- apps/code/editor_controller.cpp | 2 +- apps/hardware_test/pop_up_controller.cpp | 4 ++-- apps/shared/expression_field_delegate_app.cpp | 2 +- apps/shared/simple_interactive_curve_view_controller.h | 1 + apps/shared/text_field_delegate_app.cpp | 2 +- escher/include/escher/app.h | 4 ++++ escher/include/escher/container.h | 4 ++++ escher/include/escher/responder.h | 5 +---- escher/include/escher/warning_controller.h | 4 ++-- escher/src/app.cpp | 1 - escher/src/responder.cpp | 4 ---- escher/src/text_area.cpp | 1 + escher/src/text_field.cpp | 1 + escher/src/text_input.cpp | 2 ++ 15 files changed, 22 insertions(+), 17 deletions(-) diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index ebcb7a24a..cd4c0ceb9 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -290,7 +290,7 @@ bool ConsoleController::textFieldDidReceiveEvent(TextField * textField, Ion::Eve return true; } } - return static_cast(textField->app())->textInputDidReceiveEvent(textField, event); + return static_cast(app())->textInputDidReceiveEvent(textField, event); } bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index de2dd410e..034d960d0 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -58,7 +58,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: saveScript(); return false; } - if (static_cast(textArea->app())->textInputDidReceiveEvent(textArea, event)) { + if (static_cast(app())->textInputDidReceiveEvent(textArea, event)) { return true; } if (event == Ion::Events::EXE) { diff --git a/apps/hardware_test/pop_up_controller.cpp b/apps/hardware_test/pop_up_controller.cpp index c51b3dbe0..954bf5c13 100644 --- a/apps/hardware_test/pop_up_controller.cpp +++ b/apps/hardware_test/pop_up_controller.cpp @@ -2,6 +2,7 @@ #include #include "../apps_container.h" #include +#include namespace HardwareTest { @@ -34,8 +35,7 @@ bool PopUpController::handleEvent(Ion::Events::Event event) { PopUpController::ContentView::ContentView(Responder * parentResponder) : Responder(parentResponder), m_cancelButton(this, I18n::Message::Cancel, Invocation([](void * context, void * sender) { - PopUpController::ContentView * view = (PopUpController::ContentView *)context; - view->app()->dismissModalViewController(); + app()->dismissModalViewController(); return true; }, this), KDFont::SmallFont), m_okButton(this, I18n::Message::Ok, Invocation([](void * context, void * sender) { diff --git a/apps/shared/expression_field_delegate_app.cpp b/apps/shared/expression_field_delegate_app.cpp index 6dab7a879..2b6c9b95c 100644 --- a/apps/shared/expression_field_delegate_app.cpp +++ b/apps/shared/expression_field_delegate_app.cpp @@ -20,7 +20,7 @@ bool ExpressionFieldDelegateApp::layoutFieldShouldFinishEditing(LayoutField * la bool ExpressionFieldDelegateApp::layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) { if (layoutField->isEditing() && layoutField->shouldFinishEditing(event)) { if (!layoutField->hasText()) { - layoutField->app()->displayWarning(I18n::Message::SyntaxError); + displayWarning(I18n::Message::SyntaxError); return true; } /* An acceptable layout has to be parsable and serialized in a fixed-size diff --git a/apps/shared/simple_interactive_curve_view_controller.h b/apps/shared/simple_interactive_curve_view_controller.h index b18f468b2..6a1750d82 100644 --- a/apps/shared/simple_interactive_curve_view_controller.h +++ b/apps/shared/simple_interactive_curve_view_controller.h @@ -2,6 +2,7 @@ #define SHARED_SIMPLE_INTERACTIVE_CURVE_VIEW_CONTROLLER_H #include +#include #include "text_field_delegate.h" #include "interactive_curve_view_range.h" #include "curve_view_cursor.h" diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index ad6addf9c..95efd302f 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -25,7 +25,7 @@ bool TextFieldDelegateApp::textFieldShouldFinishEditing(TextField * textField, I bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { if (textField->isEditing() && textField->shouldFinishEditing(event)) { if (!isAcceptableText(textField->text())) { - textField->app()->displayWarning(I18n::Message::SyntaxError); + displayWarning(I18n::Message::SyntaxError); return true; } } diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index 5a0ebfb91..d4e9858a3 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -8,6 +8,7 @@ #include #include #include +#include /* An app is fed events and outputs drawing calls. * @@ -71,5 +72,8 @@ private: WarningController m_warningController; }; +// Make sure App * app() is reachable by anyone including only app.h +#include + #endif diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 0f929d8a9..52f20a53b 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -47,4 +47,8 @@ private: static Container * s_sharedContainer; }; +App * app() { + return Container::sharedContainer()->activeApp(); +} + #endif diff --git a/escher/include/escher/responder.h b/escher/include/escher/responder.h index 45b425f4f..cf84840bb 100644 --- a/escher/include/escher/responder.h +++ b/escher/include/escher/responder.h @@ -1,9 +1,7 @@ #ifndef ESCHER_RESPONDER_H #define ESCHER_RESPONDER_H -#include - -class App; +#include class Responder { public: @@ -16,7 +14,6 @@ public: Responder * parentResponder() const; Responder * commonAncestorWith(Responder * responder); void setParentResponder(Responder * responder); - App * app() const; private: Responder * m_parentResponder; }; diff --git a/escher/include/escher/warning_controller.h b/escher/include/escher/warning_controller.h index 7f4a728b5..464e1509a 100644 --- a/escher/include/escher/warning_controller.h +++ b/escher/include/escher/warning_controller.h @@ -1,10 +1,10 @@ #ifndef ESCHER_WARNING_CONTROLLER_H #define ESCHER_WARNING_CONTROLLER_H -#include +#include #include #include -#include +#include class WarningController : public ViewController { public: diff --git a/escher/src/app.cpp b/escher/src/app.cpp index 4475051d5..7d979ea95 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -101,7 +101,6 @@ void App::displayWarning(I18n::Message warningMessage1, I18n::Message warningMes void App::didBecomeActive(Window * window) { View * view = m_modalViewController.view(); - assert(m_modalViewController.app() == this); m_modalViewController.initView(); window->setContentView(view); m_modalViewController.viewWillAppear(); diff --git a/escher/src/responder.cpp b/escher/src/responder.cpp index 85fef4a17..34cbd96a0 100644 --- a/escher/src/responder.cpp +++ b/escher/src/responder.cpp @@ -61,7 +61,3 @@ Responder * Responder::commonAncestorWith(Responder * responder) { } return s; } - -App * Responder::app() const { - return Container::sharedContainer()->activeApp(); -} diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index 2aac54475..4683f121d 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 8d23fcc54..09d2531ad 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -1,3 +1,4 @@ +#include #include #include #include diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index a5cb7f293..cb9789a93 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include /* TextInput::ContentView */ From 581ec5583240f400c273b2c1b4b050e051392374 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 3 Jun 2019 14:47:56 +0200 Subject: [PATCH 052/111] [escher] Inline the App::snapshot() function --- escher/include/escher/app.h | 2 +- escher/src/app.cpp | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index d4e9858a3..c4ad4d5ad 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -46,7 +46,7 @@ public: /* The destructor has to be virtual. Otherwise calling a destructor on an * App * pointing to a Derived App would have undefined behaviour. */ virtual ~App() = default; - Snapshot * snapshot(); + Snapshot * snapshot() const { return m_snapshot; } void setFirstResponder(Responder * responder); Responder * firstResponder(); virtual bool processEvent(Ion::Events::Event event); diff --git a/escher/src/app.cpp b/escher/src/app.cpp index 7d979ea95..79d2e3c8e 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -38,10 +38,6 @@ App::App(Snapshot * snapshot, ViewController * rootViewController, I18n::Message { } -App::Snapshot * App::snapshot() { - return m_snapshot; -} - bool App::processEvent(Ion::Events::Event event) { Responder * responder = m_firstResponder; bool didHandleEvent = false; From e5f7b93efb74f84d0b9b5e38e18ec6b4b94bb4ce Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 3 Jun 2019 14:48:24 +0200 Subject: [PATCH 053/111] [apps/probability] Avoid a local snapshot cast --- apps/probability/app.h | 1 + apps/probability/calculation_controller.cpp | 3 +-- apps/probability/law_controller.cpp | 3 +-- apps/probability/parameters_controller.cpp | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/probability/app.h b/apps/probability/app.h index 12d1f3bdf..61f0a4b0d 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -54,6 +54,7 @@ public: char m_calculation[k_calculationSize]; Page m_activePage; }; + Snapshot * snapshot() const { return static_cast(::App::snapshot()); } private: App(Snapshot * snapshot); CalculationController m_calculationController; diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 007f938ab..f9dcdea43 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -79,8 +79,7 @@ CalculationController::CalculationController(Responder * parentResponder, InputE } void CalculationController::didEnterResponderChain(Responder * previousResponder) { - App::Snapshot * snapshot = (App::Snapshot *)app()->snapshot(); - snapshot->setActivePage(App::Snapshot::Page::Calculations); + app()->snapshot()->setActivePage(App::Snapshot::Page::Calculations); updateTitle(); reloadLawCurveView(); m_selectableTableView.reloadData(); diff --git a/apps/probability/law_controller.cpp b/apps/probability/law_controller.cpp index b507bb8a9..60e5eb596 100644 --- a/apps/probability/law_controller.cpp +++ b/apps/probability/law_controller.cpp @@ -73,8 +73,7 @@ void Probability::LawController::viewWillAppear() { } void Probability::LawController::didBecomeFirstResponder() { - App::Snapshot * snapshot = (App::Snapshot *)app()->snapshot(); - snapshot->setActivePage(App::Snapshot::Page::Law); + app()->snapshot()->setActivePage(App::Snapshot::Page::Law); if (selectedRow() == -1) { selectCellAtLocation(0, 0); } else { diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index def7ab459..d6bb367d2 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -99,8 +99,7 @@ void ParametersController::reinitCalculation() { } void ParametersController::didBecomeFirstResponder() { - App::Snapshot * snapshot = (App::Snapshot *)app()->snapshot(); - snapshot->setActivePage(App::Snapshot::Page::Parameters); + app()->snapshot()->setActivePage(App::Snapshot::Page::Parameters); FloatParameterController::didBecomeFirstResponder(); } From eaa47583676ed78364b137284291f687e811e1cd Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 3 Jun 2019 14:51:58 +0200 Subject: [PATCH 054/111] [apps/probability] Use namespaced App::app() function --- apps/probability/app.h | 4 ++++ apps/probability/calculation_controller.cpp | 2 +- apps/settings/app.h | 4 ++++ apps/settings/sub_menu/display_mode_controller.cpp | 3 ++- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/probability/app.h b/apps/probability/app.h index 61f0a4b0d..4cabd396a 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -63,6 +63,10 @@ private: StackViewController m_stackViewController; }; +App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index f9dcdea43..ea40bb4cb 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -267,7 +267,7 @@ void CalculationController::setCalculationAccordingToIndex(int index, bool force } TextFieldDelegateApp * CalculationController::textFieldDelegateApp() { - return (App *)app(); + return app(); } void CalculationController::updateTitle() { diff --git a/apps/settings/app.h b/apps/settings/app.h index 3f4c064d0..c534be1f8 100644 --- a/apps/settings/app.h +++ b/apps/settings/app.h @@ -25,6 +25,10 @@ private: StackViewController m_stackViewController; }; +App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/settings/sub_menu/display_mode_controller.cpp b/apps/settings/sub_menu/display_mode_controller.cpp index 945b0876a..326ca2f93 100644 --- a/apps/settings/sub_menu/display_mode_controller.cpp +++ b/apps/settings/sub_menu/display_mode_controller.cpp @@ -2,6 +2,7 @@ #include "../../shared/poincare_helpers.h" #include #include +#include "../app.h" #include @@ -95,7 +96,7 @@ bool DisplayModeController::textFieldDidFinishEditing(TextField * textField, con } Shared::TextFieldDelegateApp * DisplayModeController::textFieldDelegateApp() { - return (Shared::TextFieldDelegateApp *)app(); + return app(); } } From 21907fb89a8fe69d7d789c4705757b8d4692d7d0 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 3 Jun 2019 15:40:54 +0200 Subject: [PATCH 055/111] [apps] Get rid of App casts --- apps/calculation/app.h | 4 ++++ apps/calculation/edit_expression_controller.cpp | 14 ++++++-------- apps/calculation/history_controller.cpp | 3 +-- apps/calculation/history_view_cell.cpp | 10 ++++------ apps/code/app.h | 4 ++++ apps/code/console_controller.cpp | 4 ++-- apps/code/editor_controller.cpp | 6 +++--- apps/code/menu_controller.cpp | 2 +- apps/code/variable_box_controller.cpp | 2 +- apps/graph/app.h | 4 ++++ .../graph/calculation_graph_controller.cpp | 6 ++---- apps/graph/graph/graph_controller.cpp | 11 ++++------- apps/graph/graph/graph_controller.h | 2 +- apps/graph/graph/tangent_graph_controller.cpp | 17 +++++++---------- apps/graph/list/list_controller.cpp | 4 ++++ apps/graph/list/list_controller.h | 4 +--- .../values/derivative_parameter_controller.cpp | 3 +-- .../values/function_parameter_controller.cpp | 3 +-- apps/graph/values/values_controller.cpp | 6 +++--- apps/probability/app.h | 2 +- apps/regression/app.h | 4 ++++ apps/regression/graph_options_controller.cpp | 2 +- apps/regression/store_parameter_controller.cpp | 2 +- apps/sequence/app.h | 4 ++++ apps/sequence/graph/graph_controller.cpp | 6 +++--- apps/sequence/graph/graph_controller.h | 2 +- apps/sequence/list/list_controller.cpp | 15 +++++++-------- .../sequence/list/list_parameter_controller.cpp | 6 +++--- .../sequence/list/type_parameter_controller.cpp | 5 ++--- apps/settings/app.h | 2 +- apps/solver/app.h | 4 ++++ apps/solver/interval_controller.cpp | 5 ++--- apps/solver/list_controller.cpp | 14 ++++++-------- apps/solver/solutions_controller.cpp | 3 +-- escher/include/escher/container.h | 2 +- 35 files changed, 96 insertions(+), 91 deletions(-) diff --git a/apps/calculation/app.h b/apps/calculation/app.h index 62410ffee..0040fcd51 100644 --- a/apps/calculation/app.h +++ b/apps/calculation/app.h @@ -39,6 +39,10 @@ private: EditExpressionController m_editExpressionController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 3b30b042f..857a7f755 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -109,11 +109,11 @@ void EditExpressionController::layoutFieldDidChangeSize(::LayoutField * layoutFi } TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() { - return (App *)app(); + return app(); } ExpressionFieldDelegateApp * EditExpressionController::expressionFieldDelegateApp() { - return (App *)app(); + return app(); } void EditExpressionController::reloadView() { @@ -126,14 +126,13 @@ void EditExpressionController::reloadView() { bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event, bool shouldDuplicateLastCalculation) { if (shouldDuplicateLastCalculation && m_cacheBuffer[0] != 0) { - App * calculationApp = (App *)app(); /* The input text store in m_cacheBuffer might have beed correct the first * time but then be too long when replacing ans in another context */ - if (!calculationApp->isAcceptableText(m_cacheBuffer)) { - calculationApp->displayWarning(I18n::Message::SyntaxError); + if (!app()->isAcceptableText(m_cacheBuffer)) { + app()->displayWarning(I18n::Message::SyntaxError); return true; } - m_calculationStore->push(m_cacheBuffer, calculationApp->localContext()); + m_calculationStore->push(m_cacheBuffer, app()->localContext()); m_historyController->reload(); ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); return true; @@ -151,14 +150,13 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event bool EditExpressionController::inputViewDidFinishEditing(const char * text, Layout layoutR) { - App * calculationApp = (App *)app(); if (layoutR.isUninitialized()) { assert(text); strlcpy(m_cacheBuffer, text, k_cacheBufferSize); } else { layoutR.serializeParsedExpression(m_cacheBuffer, k_cacheBufferSize); } - m_calculationStore->push(m_cacheBuffer, calculationApp->localContext()); + m_calculationStore->push(m_cacheBuffer, app()->localContext()); m_historyController->reload(); ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); ((ContentView *)view())->expressionField()->setEditing(true, true); diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 71d193f39..8a60a1827 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -151,8 +151,7 @@ KDCoordinate HistoryController::rowHeight(int j) { return 0; } Calculation * calculation = m_calculationStore->calculationAtIndex(j); - App * calculationApp = (App *)app(); - return calculation->height(calculationApp->localContext(), j == selectedRow() && selectedSubviewType() == SubviewType::Output) + 4 * Metric::CommonSmallMargin; + return calculation->height(app()->localContext(), j == selectedRow() && selectedSubviewType() == SubviewType::Output) + 4 * Metric::CommonSmallMargin; } int HistoryController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index f886a2674..3156a46a7 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -75,8 +75,7 @@ void HistoryViewCell::reloadScroll() { } void HistoryViewCell::reloadOutputSelection() { - App * calculationApp = (App *)app(); - Calculation::DisplayOutput display = m_calculation.displayOutput(calculationApp->localContext()); + Calculation::DisplayOutput display = m_calculation.displayOutput(app()->localContext()); /* Select the right output according to the calculation display output. This * will reload the scroll to display the selected output. */ if (display == Calculation::DisplayOutput::ExactAndApproximate) { @@ -140,8 +139,7 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { // Memoization m_calculation = *calculation; m_calculationExpanded = expanded; - App * calculationApp = (App *)app(); - Calculation::DisplayOutput display = calculation->displayOutput(calculationApp->localContext()); + Calculation::DisplayOutput display = calculation->displayOutput(app()->localContext()); m_inputView.setLayout(calculation->createInputLayout()); /* Both output expressions have to be updated at the same time. Otherwise, * when updating one layout, if the second one still points to a deleted @@ -151,13 +149,13 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { if (display == Calculation::DisplayOutput::ExactOnly) { rightOutputLayout = calculation->createExactOutputLayout(); } else { - rightOutputLayout = calculation->createApproximateOutputLayout(calculationApp->localContext()); + rightOutputLayout = calculation->createApproximateOutputLayout(app()->localContext()); if (display == Calculation::DisplayOutput::ExactAndApproximate || (display == Calculation::DisplayOutput::ExactAndApproximateToggle && expanded)) { leftOutputLayout = calculation->createExactOutputLayout(); } } m_scrollableOutputView.setLayouts(rightOutputLayout, leftOutputLayout); - I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(calculationApp->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; + I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(app()->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; m_scrollableOutputView.setEqualMessage(equalMessage); /* The displayed input and outputs have changed. We need to re-layout the cell diff --git a/apps/code/app.h b/apps/code/app.h index 2c215d26a..841c54542 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -84,6 +84,10 @@ private: VariableBoxController m_variableBoxController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index cd4c0ceb9..9c2042020 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -57,7 +57,7 @@ bool ConsoleController::loadPythonEnvironment() { /* We load functions and variables names in the variable box before running * any other python code to avoid failling to load functions and variables * due to memory exhaustion. */ - static_cast(app())->variableBoxController()->loadFunctionsAndVariables(); + app()->variableBoxController()->loadFunctionsAndVariables(); return true; } @@ -290,7 +290,7 @@ bool ConsoleController::textFieldDidReceiveEvent(TextField * textField, Ion::Eve return true; } } - return static_cast(app())->textInputDidReceiveEvent(textField, event); + return app()->textInputDidReceiveEvent(textField, event); } bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index 034d960d0..6f9e4df2a 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -58,7 +58,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: saveScript(); return false; } - if (static_cast(app())->textInputDidReceiveEvent(textArea, event)) { + if (app()->textInputDidReceiveEvent(textArea, event)) { return true; } if (event == Ion::Events::EXE) { @@ -109,13 +109,13 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: } VariableBoxController * EditorController::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = static_cast(app())->variableBoxController(); + VariableBoxController * varBox = app()->variableBoxController(); varBox->loadFunctionsAndVariables(); return varBox; } InputEventHandlerDelegateApp * EditorController::inputEventHandlerDelegateApp() { - return static_cast(app()); + return app(); } StackViewController * EditorController::stackController() { diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index c9378bcbe..dabd1e7a8 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -36,7 +36,7 @@ MenuController::MenuController(Responder * parentResponder, App * pythonDelegate } ConsoleController * MenuController::consoleController() { - return static_cast(app())->consoleController(); + return app()->consoleController(); } StackViewController * MenuController::stackViewController() { diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index 13f086a57..b8345ec01 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -33,7 +33,7 @@ void VariableBoxController::didEnterResponderChain(Responder * previousFirstResp * environment where Python has already been inited. This way, we do not * deinit Python when leaving the VariableBoxController, so we do not lose the * environment that was loaded when entering the VariableBoxController. */ - assert(static_cast(app())->pythonIsInited()); + assert(app()->pythonIsInited()); } static bool shouldAddObject(const char * name, int maxLength) { diff --git a/apps/graph/app.h b/apps/graph/app.h index 1a7fdbf6a..362dfe858 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -52,6 +52,10 @@ private: InputViewController m_inputViewController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/graph/graph/calculation_graph_controller.cpp b/apps/graph/graph/calculation_graph_controller.cpp index e72b21167..bb9513eec 100644 --- a/apps/graph/graph/calculation_graph_controller.cpp +++ b/apps/graph/graph/calculation_graph_controller.cpp @@ -45,16 +45,14 @@ void CalculationGraphController::reloadBannerView() { } Expression::Coordinate2D CalculationGraphController::computeNewPointOfInteresetFromAbscissa(double start, int direction) { - App * myApp = static_cast(app()); double step = m_graphRange->xGridUnit()/10.0; step = direction < 0 ? -step : step; double max = direction > 0 ? m_graphRange->xMax() : m_graphRange->xMin(); - return computeNewPointOfInterest(start, step, max, myApp->localContext()); + return computeNewPointOfInterest(start, step, max, app()->localContext()); } CartesianFunctionStore * CalculationGraphController::functionStore() const { - App * a = static_cast(app()); - return a->functionStore(); + return app()->functionStore(); } bool CalculationGraphController::handleLeftRightEvent(Ion::Events::Event event) { diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 23e5e2e23..b07587948 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -7,7 +7,7 @@ namespace Graph { static inline float maxFloat(float x, float y) { return x > y ? x : y; } -GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : +GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, curveViewRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion), m_bannerView(this, inputEventHandlerDelegate, this), m_view(functionStore, curveViewRange, m_cursor, &m_bannerView, &m_cursorView), @@ -43,10 +43,9 @@ void GraphController::setDisplayDerivativeInBanner(bool displayDerivative) { float GraphController::interestingXHalfRange() const { float characteristicRange = 0.0f; - TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - float fRange = f->expressionReduced(myApp->localContext()).characteristicXRange(*(myApp->localContext()), Poincare::Preferences::sharedPreferences()->angleUnit()); + float fRange = f->expressionReduced(app()->localContext()).characteristicXRange(*(app()->localContext()), Poincare::Preferences::sharedPreferences()->angleUnit()); if (!std::isnan(fRange)) { characteristicRange = maxFloat(fRange, characteristicRange); } @@ -74,14 +73,12 @@ void GraphController::reloadBannerView() { return; } Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()); - App * myApp = static_cast(app()); - reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, record, myApp); + reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, record, app()); } bool GraphController::moveCursorHorizontally(int direction) { Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()); - App * myApp = static_cast(app()); - return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, record, myApp); + return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, record, app()); } InteractiveCurveViewRange * GraphController::interactiveCurveViewRange() { diff --git a/apps/graph/graph/graph_controller.h b/apps/graph/graph/graph_controller.h index b81df43d4..2b7719e27 100644 --- a/apps/graph/graph/graph_controller.h +++ b/apps/graph/graph/graph_controller.h @@ -15,7 +15,7 @@ namespace Graph { class GraphController : public Shared::FunctionGraphController, public GraphControllerHelper { public: - GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header); + GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, CartesianFunctionStore * functionStore, Shared::InteractiveCurveViewRange * curveViewRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header); I18n::Message emptyMessage() override; void viewWillAppear() override; bool displayDerivativeInBanner() const; diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 5f11be357..805c57240 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -43,8 +43,7 @@ bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, co if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { return false; } - App * myApp = static_cast(app()); - ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); + ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); double y = function->evaluateAtAbscissa(floatBody, textFieldDelegateApp()->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); @@ -62,29 +61,27 @@ void TangentGraphController::reloadBannerView() { if (m_record.isNull()) { return; } - App * myApp = static_cast(app()); - FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, myApp->functionStore(), CartesianFunction::Symbol()); - GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record, myApp); + FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, app()->functionStore(), CartesianFunction::Symbol()); + GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record, app()); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * legend = "a="; int legendLength = strlcpy(buffer, legend, bufferSize); - ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); - double y = function->approximateDerivative(m_cursor->x(), myApp->localContext()); + ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); + double y = function->approximateDerivative(m_cursor->x(), app()->localContext()); PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); m_bannerView->aView()->setText(buffer); legend = "b="; legendLength = strlcpy(buffer, legend, bufferSize); - y = -y*m_cursor->x()+function->evaluateAtAbscissa(m_cursor->x(), myApp->localContext()); + y = -y*m_cursor->x()+function->evaluateAtAbscissa(m_cursor->x(), app()->localContext()); PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); m_bannerView->bView()->setText(buffer); m_bannerView->reload(); } bool TangentGraphController::moveCursorHorizontally(int direction) { - App * myApp = static_cast(app()); - return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_record, myApp); + return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_record, app()); } bool TangentGraphController::handleEnter() { diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 5d7a26a02..751634b06 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -189,4 +189,8 @@ void ListController::setFunctionNameInTextField(ExpiringPointer functi textField->setText(bufferName); } +Shared::TextFieldDelegateApp * ListController::textFieldDelegateApp() { + return app(); +} + } diff --git a/apps/graph/list/list_controller.h b/apps/graph/list/list_controller.h index 2841df254..a4e439b4b 100644 --- a/apps/graph/list/list_controller.h +++ b/apps/graph/list/list_controller.h @@ -29,9 +29,7 @@ private: HighlightCell * expressionCells(int index) override; void willDisplayTitleCellAtIndex(HighlightCell * cell, int j) override; void willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) override; - Shared::TextFieldDelegateApp * textFieldDelegateApp() override { - return static_cast(app()); - } + Shared::TextFieldDelegateApp * textFieldDelegateApp() override; void setFunctionNameInTextField(Shared::ExpiringPointer function, TextField * textField); TextFieldFunctionTitleCell m_functionTitleCells[k_maxNumberOfDisplayableRows]; Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfDisplayableRows]; diff --git a/apps/graph/values/derivative_parameter_controller.cpp b/apps/graph/values/derivative_parameter_controller.cpp index c7d44b95e..4a411bf58 100644 --- a/apps/graph/values/derivative_parameter_controller.cpp +++ b/apps/graph/values/derivative_parameter_controller.cpp @@ -82,8 +82,7 @@ KDCoordinate DerivativeParameterController::cellHeight() { } CartesianFunctionStore * DerivativeParameterController::functionStore() { - App * a = static_cast(app()); - return a->functionStore(); + return app()->functionStore(); } } diff --git a/apps/graph/values/function_parameter_controller.cpp b/apps/graph/values/function_parameter_controller.cpp index 2ceca2e65..a95d14373 100644 --- a/apps/graph/values/function_parameter_controller.cpp +++ b/apps/graph/values/function_parameter_controller.cpp @@ -70,8 +70,7 @@ void FunctionParameterController::willDisplayCellForIndex(HighlightCell * cell, } ExpiringPointer FunctionParameterController::function() { - App * a = static_cast(app()); - return a->functionStore()->modelForRecord(m_record); + return app()->functionStore()->modelForRecord(m_record); } } diff --git a/apps/graph/values/values_controller.cpp b/apps/graph/values/values_controller.cpp index 85310c9ca..46e0e5123 100644 --- a/apps/graph/values/values_controller.cpp +++ b/apps/graph/values/values_controller.cpp @@ -1,6 +1,7 @@ #include "values_controller.h" #include #include "../../constant.h" +#include "../app.h" using namespace Shared; using namespace Poincare; @@ -142,15 +143,14 @@ FunctionParameterController * ValuesController::functionParameterController() { } double ValuesController::evaluationOfAbscissaAtColumn(double abscissa, int columnIndex) { - TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); bool isDerivative = isDerivativeColumn(columnIndex); /* isDerivativeColumn uses expiring pointers, so "function" must be created * after the isDerivativeColumn call, else it will expire. */ Shared::ExpiringPointer function = functionStore()->modelForRecord(recordAtColumn(columnIndex)); if (isDerivative) { - return function->approximateDerivative(abscissa, myApp->localContext()); + return function->approximateDerivative(abscissa, app()->localContext()); } - return function->evaluateAtAbscissa(abscissa, myApp->localContext()); + return function->evaluateAtAbscissa(abscissa, app()->localContext()); } void ValuesController::updateNumberOfColumns() { diff --git a/apps/probability/app.h b/apps/probability/app.h index 4cabd396a..a8cdd606d 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -63,7 +63,7 @@ private: StackViewController m_stackViewController; }; -App * app() { +inline App * app() { return static_cast(::app()); } diff --git a/apps/regression/app.h b/apps/regression/app.h index f19a4d113..06f443195 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -57,6 +57,10 @@ private: RegressionController m_regressionController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/regression/graph_options_controller.cpp b/apps/regression/graph_options_controller.cpp index eec852d66..642f43ef9 100644 --- a/apps/regression/graph_options_controller.cpp +++ b/apps/regression/graph_options_controller.cpp @@ -42,7 +42,7 @@ void GraphOptionsController::viewWillAppear() { bool GraphOptionsController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { if (selectedRow() == numberOfRows() -1) { - RegressionController * regressionController = static_cast(app())->regressionController(); + RegressionController * regressionController = app()->regressionController(); regressionController->setSeries(m_graphController->selectedSeriesIndex()); StackViewController * stack = static_cast(parentResponder()); stack->push(regressionController); diff --git a/apps/regression/store_parameter_controller.cpp b/apps/regression/store_parameter_controller.cpp index 285ddd7df..a82408cd5 100644 --- a/apps/regression/store_parameter_controller.cpp +++ b/apps/regression/store_parameter_controller.cpp @@ -20,7 +20,7 @@ void StoreParameterController::viewWillAppear() { bool StoreParameterController::handleEvent(Ion::Events::Event event) { if ((event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) && selectedRow() == numberOfRows() - 1) { - RegressionController * regressionController = static_cast(app())->regressionController(); + RegressionController * regressionController = app()->regressionController(); regressionController->setSeries(m_series); StackViewController * stack = static_cast(parentResponder()); stack->push(regressionController); diff --git a/apps/sequence/app.h b/apps/sequence/app.h index 02c215f77..1201105fe 100644 --- a/apps/sequence/app.h +++ b/apps/sequence/app.h @@ -58,6 +58,10 @@ private: InputViewController m_inputViewController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 4e10f4df0..97351f460 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -1,6 +1,7 @@ #include "graph_controller.h" #include #include +#include "../app.h" using namespace Shared; using namespace Poincare; @@ -10,7 +11,7 @@ namespace Sequence { static inline int minInt(int x, int y) { return (x < y ? x : y); } static inline int maxInt(int x, int y) { return (x > y ? x : y); } -GraphController::GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : +GraphController::GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header) : FunctionGraphController(parentResponder, inputEventHandlerDelegate, header, graphRange, &m_view, cursor, indexFunctionSelectedByCursor, modelVersion, rangeVersion, angleUnitVersion), m_bannerView(this, inputEventHandlerDelegate, this), m_view(sequenceStore, graphRange, m_cursor, &m_bannerView, &m_cursorView), @@ -95,8 +96,7 @@ bool GraphController::moveCursorHorizontally(int direction) { return false; } Sequence * s = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor())); - TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); - double y = s->evaluateAtAbscissa(x, myApp->localContext()); + double y = s->evaluateAtAbscissa(x, app()->localContext()); m_cursor->moveTo(x, y); return true; } diff --git a/apps/sequence/graph/graph_controller.h b/apps/sequence/graph/graph_controller.h index d9230c1d8..5d538ec78 100644 --- a/apps/sequence/graph/graph_controller.h +++ b/apps/sequence/graph/graph_controller.h @@ -14,7 +14,7 @@ namespace Sequence { class GraphController final : public Shared::FunctionGraphController { public: - GraphController(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header); + GraphController(Responder * parentResponder, ::InputEventHandlerDelegate * inputEventHandlerDelegate, SequenceStore * sequenceStore, CurveViewRange * graphRange, Shared::CurveViewCursor * cursor, int * indexFunctionSelectedByCursor, uint32_t * modelVersion, uint32_t * rangeVersion, Poincare::Preferences::AngleUnit * angleUnitVersion, ButtonRowController * header); I18n::Message emptyMessage() override; void viewWillAppear() override; TermSumController * termSumController() { return &m_termSumController; } diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index 3a38c38a7..a066517f3 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -107,10 +107,9 @@ void ListController::editExpression(int sequenceDefinition, Ion::Events::Event e // Replace UCodePointUnknownN with 'n' replaceUnknownSymbolWithReadableSymbol(initialText); } - App * myApp = (App *)app(); - InputViewController * inputController = myApp->inputViewController(); + InputViewController * inputController = app()->inputViewController(); // Invalidate the sequences context cache - static_cast(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); switch (sequenceDefinition) { case 0: inputController->edit(this, event, this, initialText, @@ -160,15 +159,15 @@ bool ListController::editInitialConditionOfSelectedRecordWithText(const char * t } TextFieldDelegateApp * ListController::textFieldDelegateApp() { - return (App *)app(); + return app(); } ExpressionFieldDelegateApp * ListController::expressionFieldDelegateApp() { - return (App *)app(); + return app(); } InputEventHandlerDelegateApp * ListController::inputEventHandlerDelegateApp() { - return (App *)app(); + return app(); } ListParameterController * ListController::parameterController() { @@ -280,7 +279,7 @@ void ListController::editExpression(Ion::Events::Event event) { void ListController::reinitSelectedExpression(ExpiringPointer model) { // Invalidate the sequences context cache - static_cast(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); Sequence * sequence = static_cast(model.pointer()); switch (sequenceDefinitionForRow(selectedRow())) { case 1: @@ -308,7 +307,7 @@ void ListController::reinitSelectedExpression(ExpiringPointer(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); return true; } diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index fac6aba66..28d6472c0 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -56,7 +56,7 @@ bool ListParameterController::handleEvent(Ion::Events::Event event) { #else if (selectedRowIndex == 2+hasAdditionalRow) { #endif - static_cast(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); return handleEnterOnRow(selectedRowIndex-hasAdditionalRow-1); } } @@ -82,7 +82,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c } sequence()->setInitialRank(index); // Invalidate sequence context cache when changing sequence type - static_cast(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); m_selectableTableView.reloadCellAtLocation(0, selectedRow()); m_selectableTableView.handleEvent(event); return true; @@ -149,7 +149,7 @@ void ListParameterController::willDisplayCellForIndex(HighlightCell * cell, int } TextFieldDelegateApp * ListParameterController::textFieldDelegateApp() { - return (TextFieldDelegateApp *)app(); + return app(); } int ListParameterController::totalNumberOfCells() const { diff --git a/apps/sequence/list/type_parameter_controller.cpp b/apps/sequence/list/type_parameter_controller.cpp index aa2e9b4e7..de2c8d35a 100644 --- a/apps/sequence/list/type_parameter_controller.cpp +++ b/apps/sequence/list/type_parameter_controller.cpp @@ -60,7 +60,7 @@ bool TypeParameterController::handleEvent(Ion::Events::Event event) { m_listController->selectPreviousNewSequenceCell(); sequence()->setType(sequenceType); // Invalidate sequence context cache when changing sequence type - static_cast(app())->localContext()->resetCache(); + app()->localContext()->resetCache(); // Reset the first index if the new type is "Explicit" if (sequenceType == Sequence::Type::Explicit) { sequence()->setInitialRank(0); @@ -135,8 +135,7 @@ void TypeParameterController::setRecord(Ion::Storage::Record record) { } SequenceStore * TypeParameterController::sequenceStore() { - App * a = static_cast(app()); - return a->functionStore(); + return app()->functionStore(); } StackViewController * TypeParameterController::stackController() const { diff --git a/apps/settings/app.h b/apps/settings/app.h index c534be1f8..3189364d4 100644 --- a/apps/settings/app.h +++ b/apps/settings/app.h @@ -25,7 +25,7 @@ private: StackViewController m_stackViewController; }; -App * app() { +inline App * app() { return static_cast(::app()); } diff --git a/apps/solver/app.h b/apps/solver/app.h index d9c8cae6a..cf62f7b5b 100644 --- a/apps/solver/app.h +++ b/apps/solver/app.h @@ -45,6 +45,10 @@ private: InputViewController m_inputViewController; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/solver/interval_controller.cpp b/apps/solver/interval_controller.cpp index 19d061602..19b1c5aed 100644 --- a/apps/solver/interval_controller.cpp +++ b/apps/solver/interval_controller.cpp @@ -103,9 +103,8 @@ bool IntervalController::textFieldDidFinishEditing(TextField * textField, const void IntervalController::buttonAction() { StackViewController * stack = stackController(); - App * solverApp = static_cast(app()); - m_equationStore->approximateSolve(solverApp->localContext()); - stack->push(solverApp->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); + m_equationStore->approximateSolve(app()->localContext()); + stack->push(app()->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); } } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index bd8cb69a0..6b8429713 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -175,7 +175,7 @@ void ListController::resolveEquations() { app()->displayWarning(I18n::Message::EnterEquation); return; } - EquationStore::Error e = m_equationStore->exactSolve(static_cast(app())->localContext()); + EquationStore::Error e = m_equationStore->exactSolve(app()->localContext()); switch (e) { case EquationStore::Error::EquationUndefined: app()->displayWarning(I18n::Message::UndefinedEquation); @@ -192,16 +192,14 @@ void ListController::resolveEquations() { case EquationStore::Error::RequireApproximateSolution: { StackViewController * stack = stackController(); - App * solverApp = static_cast(app()); - stack->push(solverApp->intervalController(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(app()->intervalController(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); return; } default: { assert(e == EquationStore::Error::NoError); StackViewController * stack = stackController(); - App * solverApp = static_cast(app()); - stack->push(solverApp->solutionsControllerStack(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(app()->solutionsControllerStack(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); } } } @@ -231,11 +229,11 @@ SelectableTableView * ListController::selectableTableView() { } Shared::TextFieldDelegateApp * ListController::textFieldDelegateApp() { - return static_cast(app()); + return app(); } Shared::ExpressionFieldDelegateApp * ListController::expressionFieldDelegateApp() { - return static_cast(app()); + return app(); } StackViewController * ListController::stackController() const { @@ -243,7 +241,7 @@ StackViewController * ListController::stackController() const { } InputViewController * ListController::inputController() { - return static_cast(app())->inputViewController(); + return app()->inputViewController(); } } diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index dcb422691..2da207c87 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -105,11 +105,10 @@ View * SolutionsController::view() { void SolutionsController::viewWillAppear() { ViewController::viewWillAppear(); - App * solverApp = static_cast(app()); bool requireWarning = false; if (m_equationStore->type() == EquationStore::Type::Monovariable) { m_contentView.setWarningMessages(I18n::Message::OnlyFirstSolutionsDisplayed0, I18n::Message::OnlyFirstSolutionsDisplayed1); - requireWarning = m_equationStore->haveMoreApproximationSolutions(solverApp->localContext()); + requireWarning = m_equationStore->haveMoreApproximationSolutions(app()->localContext()); } else if (m_equationStore->type() == EquationStore::Type::PolynomialMonovariable && m_equationStore->numberOfSolutions() == 1) { assert(Preferences::sharedPreferences()->complexFormat() == Preferences::ComplexFormat::Real); m_contentView.setWarningMessages(I18n::Message::PolynomeHasNoRealSolution0, I18n::Message::PolynomeHasNoRealSolution1); diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 52f20a53b..9d70aa331 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -47,7 +47,7 @@ private: static Container * s_sharedContainer; }; -App * app() { +inline App * app() { return Container::sharedContainer()->activeApp(); } From a124f456c63ae2fed06c6d3e69caac510c676bd7 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 27 Jun 2019 13:49:52 +0200 Subject: [PATCH 056/111] [apps/home/controller] Remove dummy --- apps/home/controller.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index e4ca4b43e..f205076bb 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -80,8 +80,6 @@ bool Controller::handleEvent(Ion::Events::Event event) { void Controller::didBecomeFirstResponder() { if (m_selectionDataSource->selectedRow() == -1) { m_selectionDataSource->selectCellAtLocation(0, 0); - } else { - m_selectionDataSource->selectCellAtLocation(m_selectionDataSource->selectedColumn(), m_selectionDataSource->selectedRow()); } app()->setFirstResponder(m_view.selectableTableView()); } From 0702212cfe082fe92c84156a6ecd624b5a5e5bfc Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 27 Jun 2019 13:51:52 +0200 Subject: [PATCH 057/111] [apps/home] Select cell on Snapshot's construction --- apps/home/app.h | 1 + apps/home/controller.cpp | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/home/app.h b/apps/home/app.h index cdbf95b1b..f54b78d4a 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -15,6 +15,7 @@ public: }; class Snapshot : public ::App::Snapshot, public SelectableTableViewDataSource { public: + Snapshot() { selectCellAtLocation(0, 0); } App * unpack(Container * container) override; Descriptor * descriptor() override; }; diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index f205076bb..262c68186 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -78,9 +78,6 @@ bool Controller::handleEvent(Ion::Events::Event event) { } void Controller::didBecomeFirstResponder() { - if (m_selectionDataSource->selectedRow() == -1) { - m_selectionDataSource->selectCellAtLocation(0, 0); - } app()->setFirstResponder(m_view.selectableTableView()); } From bcf2fda882a3f45f7f81bac70d2043d58acb8937 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 27 Jun 2019 14:01:18 +0200 Subject: [PATCH 058/111] [apps/home] Access to SelectableTableViewDataSource directly from App --- apps/home/app.h | 7 +++++++ apps/home/controller.cpp | 18 +++++++++++------- apps/home/controller.h | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/home/app.h b/apps/home/app.h index f54b78d4a..16335ad97 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -19,11 +19,18 @@ public: App * unpack(Container * container) override; Descriptor * descriptor() override; }; + Snapshot * snapshot() const { + return static_cast(::App::snapshot()); + } private: App(Snapshot * snapshot); Controller m_controller; }; +inline App * app() { + return static_cast(::app()); +} + } #endif diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 262c68186..2d98b6f88 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -1,4 +1,5 @@ #include "controller.h" +#include "app.h" #include "../apps_container.h" extern "C" { #include @@ -49,15 +50,14 @@ void Controller::ContentView::layoutSubviews() { Controller::Controller(Responder * parentResponder, SelectableTableViewDataSource * selectionDataSource) : ViewController(parentResponder), - m_view(this, selectionDataSource), - m_selectionDataSource(selectionDataSource) + m_view(this, selectionDataSource) { } bool Controller::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { AppsContainer * container = AppsContainer::sharedAppsContainer(); - bool switched = container->switchTo(container->appSnapshotAtIndex(m_selectionDataSource->selectedRow()*k_numberOfColumns+m_selectionDataSource->selectedColumn()+1)); + bool switched = container->switchTo(container->appSnapshotAtIndex(selectionDataSource()->selectedRow()*k_numberOfColumns+selectionDataSource()->selectedColumn()+1)); assert(switched); (void) switched; // Silence compilation warning about unused variable. return true; @@ -67,11 +67,11 @@ bool Controller::handleEvent(Ion::Events::Event event) { return m_view.selectableTableView()->selectCellAtLocation(0,0); } - if (event == Ion::Events::Right && m_selectionDataSource->selectedRow() < numberOfRows()) { - return m_view.selectableTableView()->selectCellAtLocation(0, m_selectionDataSource->selectedRow()+1); + if (event == Ion::Events::Right && selectionDataSource()->selectedRow() < numberOfRows()) { + return m_view.selectableTableView()->selectCellAtLocation(0, selectionDataSource()->selectedRow()+1); } - if (event == Ion::Events::Left && m_selectionDataSource->selectedRow() > 0) { - return m_view.selectableTableView()->selectCellAtLocation(numberOfColumns()-1, m_selectionDataSource->selectedRow()-1); + if (event == Ion::Events::Left && selectionDataSource()->selectedRow() > 0) { + return m_view.selectableTableView()->selectCellAtLocation(numberOfColumns()-1, selectionDataSource()->selectedRow()-1); } return false; @@ -158,4 +158,8 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo } } +SelectableTableViewDataSource * Controller::selectionDataSource() const { + return app()->snapshot(); +} + } diff --git a/apps/home/controller.h b/apps/home/controller.h index a7762d433..7750f1cb1 100644 --- a/apps/home/controller.h +++ b/apps/home/controller.h @@ -26,6 +26,7 @@ public: void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override; private: int numberOfIcons(); + SelectableTableViewDataSource * selectionDataSource() const; class ContentView : public View { public: ContentView(Controller * controller, SelectableTableViewDataSource * selectionDataSource); @@ -47,7 +48,6 @@ private: static constexpr int k_cellWidth = 104; ContentView m_view; AppCell m_cells[k_maxNumberOfCells]; - SelectableTableViewDataSource * m_selectionDataSource; }; } From e4ec398ecd65807d5d425f3e0f69a1221275ee26 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 14:04:47 +0200 Subject: [PATCH 059/111] [escher] InputEventHandler gets the app directly --- escher/include/escher/input_event_handler.h | 5 ++--- escher/src/input_event_handler.cpp | 4 ++-- escher/src/layout_field.cpp | 2 +- escher/src/text_area.cpp | 3 +-- escher/src/text_field.cpp | 3 +-- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/escher/include/escher/input_event_handler.h b/escher/include/escher/input_event_handler.h index b413eef6d..c033e1055 100644 --- a/escher/include/escher/input_event_handler.h +++ b/escher/include/escher/input_event_handler.h @@ -1,17 +1,16 @@ #ifndef ESCHER_INPUT_EVENT_HANDLER_H #define ESCHER_INPUT_EVENT_HANDLER_H -#include +#include class InputEventHandlerDelegate; -class App; class InputEventHandler { public: InputEventHandler(InputEventHandlerDelegate * inputEventHandlerdelegate) : m_inputEventHandlerDelegate(inputEventHandlerdelegate) {} virtual bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) { return false; } protected: - bool handleBoxEvent(App * app, Ion::Events::Event event); + bool handleBoxEvent(Ion::Events::Event event); InputEventHandlerDelegate * m_inputEventHandlerDelegate; }; diff --git a/escher/src/input_event_handler.cpp b/escher/src/input_event_handler.cpp index aa2f2a0af..c99fc6524 100644 --- a/escher/src/input_event_handler.cpp +++ b/escher/src/input_event_handler.cpp @@ -4,7 +4,7 @@ #include #include -bool InputEventHandler::handleBoxEvent(App * app, Ion::Events::Event event) { +bool InputEventHandler::handleBoxEvent(Ion::Events::Event event) { NestedMenuController * box = nullptr; if (m_inputEventHandlerDelegate) { box = event == Ion::Events::Toolbox ? m_inputEventHandlerDelegate->toolboxForInputEventHandler(this) : box; @@ -12,7 +12,7 @@ bool InputEventHandler::handleBoxEvent(App * app, Ion::Events::Event event) { } if (box) { box->setSender(this); - app->displayModalViewController(box, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin); + app()->displayModalViewController(box, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin); return true; } return false; diff --git a/escher/src/layout_field.cpp b/escher/src/layout_field.cpp index b691b73b8..0e5d44da3 100644 --- a/escher/src/layout_field.cpp +++ b/escher/src/layout_field.cpp @@ -174,7 +174,7 @@ bool LayoutField::privateHandleEvent(Ion::Events::Event event) { if (m_delegate && m_delegate->layoutFieldDidReceiveEvent(this, event)) { return true; } - if (handleBoxEvent(app(), event)) { + if (handleBoxEvent(event)) { if (!isEditing()) { setEditing(true); } diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index 4683f121d..89b4abde2 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -97,7 +96,7 @@ bool TextArea::handleEventWithText(const char * text, bool indentation, bool for bool TextArea::handleEvent(Ion::Events::Event event) { if (m_delegate != nullptr && m_delegate->textAreaDidReceiveEvent(this, event)) { return true; - } else if (handleBoxEvent(app(), event)) { + } else if (handleBoxEvent(event)) { return true; } else if (event == Ion::Events::Left) { return TextInput::moveCursorLeft(); diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 09d2531ad..d85ce90de 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -278,7 +277,7 @@ void TextField::setEditing(bool isEditing, bool reinitDrafBuffer) { bool TextField::privateHandleEvent(Ion::Events::Event event) { // Handle Toolbox or Var event - if (handleBoxEvent(app(), event)) { + if (handleBoxEvent(event)) { if (!isEditing()) { setEditing(true); } From 2888eddd0617fde508fe69768862811c925cd4fa Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 14:11:23 +0200 Subject: [PATCH 060/111] [escher/button_row_controller] Access the app directly --- escher/include/escher/button_row_controller.h | 3 +-- escher/src/button_row_controller.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/escher/include/escher/button_row_controller.h b/escher/include/escher/button_row_controller.h index 879c1b5d7..dcba3c98f 100644 --- a/escher/include/escher/button_row_controller.h +++ b/escher/include/escher/button_row_controller.h @@ -6,7 +6,6 @@ #include #include #include -#include #include class ButtonRowDelegate; @@ -48,7 +47,7 @@ private: View * subviewAtIndex(int index) override; void layoutSubviews() override; void drawRect(KDContext * ctx, KDRect rect) const override; - bool setSelectedButton(int selectedButton, App * app); + bool setSelectedButton(int selectedButton); int selectedButton() const { return m_selectedButton; } ViewController * mainViewController() const { return m_mainViewController; } ButtonRowDelegate * buttonRowDelegate() const { return m_delegate; } diff --git a/escher/src/button_row_controller.cpp b/escher/src/button_row_controller.cpp index 941415889..a010d054d 100644 --- a/escher/src/button_row_controller.cpp +++ b/escher/src/button_row_controller.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -141,7 +142,7 @@ void ButtonRowController::ContentView::drawRect(KDContext * ctx, KDRect rect) co } } -bool ButtonRowController::ContentView::setSelectedButton(int selectedButton, App * application) { +bool ButtonRowController::ContentView::setSelectedButton(int selectedButton) { if (selectedButton < -1 || selectedButton >= numberOfButtons() || selectedButton == m_selectedButton) { return false; } @@ -153,7 +154,7 @@ bool ButtonRowController::ContentView::setSelectedButton(int selectedButton, App if (m_selectedButton >= 0) { Button * button = buttonAtIndex(selectedButton); button->setHighlighted(true); - application->setFirstResponder(button); + app()->setFirstResponder(button); return true; } return false; @@ -178,8 +179,7 @@ int ButtonRowController::selectedButton() { } bool ButtonRowController::setSelectedButton(int selectedButton) { - App * application = app(); - return m_contentView.setSelectedButton(selectedButton, application); + return m_contentView.setSelectedButton(selectedButton); } void ButtonRowController::setMessageOfButtonAtIndex(I18n::Message message, int index) { From 4111927bae215016762c87e465782593e2a844b0 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 17:01:04 +0200 Subject: [PATCH 061/111] [apps] Access *DelegateApp() through app() --- apps/calculation/edit_expression_controller.cpp | 4 ++-- apps/graph/graph/tangent_graph_controller.cpp | 6 +++--- apps/probability/calculation_controller.cpp | 2 +- apps/sequence/graph/graph_controller.cpp | 4 ++-- apps/sequence/list/list_parameter_controller.cpp | 2 +- apps/settings/sub_menu/display_mode_controller.cpp | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 857a7f755..1111e50e4 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -69,7 +69,7 @@ bool EditExpressionController::textFieldDidReceiveEvent(::TextField * textField, if (inputViewDidReceiveEvent(event, shouldDuplicateLastCalculation)) { return true; } - return textFieldDelegateApp()->textFieldDidReceiveEvent(textField, event); + return app()->textFieldDidReceiveEvent(textField, event); } bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) { @@ -85,7 +85,7 @@ bool EditExpressionController::layoutFieldDidReceiveEvent(::LayoutField * layout if (inputViewDidReceiveEvent(event, shouldDuplicateLastCalculation)) { return true; } - return expressionFieldDelegateApp()->layoutFieldDidReceiveEvent(layoutField, event); + return app()->layoutFieldDidReceiveEvent(layoutField, event); } bool EditExpressionController::layoutFieldDidFinishEditing(::LayoutField * layoutField, Layout layoutR, Ion::Events::Event event) { diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 805c57240..46b61eb1c 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -33,18 +33,18 @@ void TangentGraphController::viewWillAppear() { void TangentGraphController::didBecomeFirstResponder() { if (curveView()->isMainViewSelected()) { m_bannerView->abscissaValue()->setParentResponder(this); - m_bannerView->abscissaValue()->setDelegates(textFieldDelegateApp(), this); + m_bannerView->abscissaValue()->setDelegates(app(), this); app()->setFirstResponder(m_bannerView->abscissaValue()); } } bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + if (app()->hasUndefinedValue(text, floatBody)) { return false; } ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); - double y = function->evaluateAtAbscissa(floatBody, textFieldDelegateApp()->localContext()); + double y = function->evaluateAtAbscissa(floatBody, app()->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); reloadBannerView(); diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index ea40bb4cb..0ab3a4e28 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -211,7 +211,7 @@ bool CalculationController::textFieldShouldFinishEditing(TextField * textField, bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + if (app()->hasUndefinedValue(text, floatBody)) { return false; } if (m_calculation->type() != Calculation::Type::FiniteIntegral && selectedColumn() == 2) { diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 97351f460..68c0a1097 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -62,11 +62,11 @@ float GraphController::interestingXHalfRange() const { bool GraphController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + if (app()->hasUndefinedValue(text, floatBody)) { return false; } floatBody = std::fmax(0, std::round(floatBody)); - double y = yValue(selectedCurveIndex(), floatBody, textFieldDelegateApp()->localContext()); + double y = yValue(selectedCurveIndex(), floatBody, app()->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); reloadBannerView(); diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 28d6472c0..722b86041 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -72,7 +72,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c /* -1 to take into account a double recursive sequence, which has * SecondIndex = FirstIndex + 1 */ double floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + if (app()->hasUndefinedValue(text, floatBody)) { return false; } int index = std::round(floatBody); diff --git a/apps/settings/sub_menu/display_mode_controller.cpp b/apps/settings/sub_menu/display_mode_controller.cpp index 326ca2f93..35b6a6fbe 100644 --- a/apps/settings/sub_menu/display_mode_controller.cpp +++ b/apps/settings/sub_menu/display_mode_controller.cpp @@ -78,7 +78,7 @@ bool DisplayModeController::textFieldShouldFinishEditing(TextField * textField, bool DisplayModeController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { + if (app()->hasUndefinedValue(text, floatBody)) { return false; } if (floatBody < 1) { From 0490e3ab81f56b56f2d310e2dc8fb2e47de4d5fa Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 17:28:33 +0200 Subject: [PATCH 062/111] [apps] Define InputEventHandlerDelegate::inputEventHandlerDelegateApp() directly from ::app() --- apps/code/editor_controller.cpp | 4 ---- apps/code/editor_controller.h | 1 - apps/sequence/list/list_controller.cpp | 4 ---- apps/sequence/list/list_controller.h | 1 - apps/shared/input_event_handler_delegate.h | 5 +++-- apps/shared/input_event_handler_delegate_app.h | 3 ++- 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index 6f9e4df2a..b07470d88 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -114,10 +114,6 @@ VariableBoxController * EditorController::variableBoxForInputEventHandler(InputE return varBox; } -InputEventHandlerDelegateApp * EditorController::inputEventHandlerDelegateApp() { - return app(); -} - StackViewController * EditorController::stackController() { return static_cast(parentResponder()); } diff --git a/apps/code/editor_controller.h b/apps/code/editor_controller.h index 93e3adb60..7020ad14f 100644 --- a/apps/code/editor_controller.h +++ b/apps/code/editor_controller.h @@ -33,7 +33,6 @@ public: VariableBoxController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; private: - Shared::InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() override; static constexpr int k_indentationSpacesNumber = 2; //TODO LEA merge with text area k_indentationSpaces StackViewController * stackController(); void saveScript(); diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index a066517f3..a884590e0 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -166,10 +166,6 @@ ExpressionFieldDelegateApp * ListController::expressionFieldDelegateApp() { return app(); } -InputEventHandlerDelegateApp * ListController::inputEventHandlerDelegateApp() { - return app(); -} - ListParameterController * ListController::parameterController() { return &m_parameterController; } diff --git a/apps/sequence/list/list_controller.h b/apps/sequence/list/list_controller.h index e7b639471..7d564ce9c 100644 --- a/apps/sequence/list/list_controller.h +++ b/apps/sequence/list/list_controller.h @@ -30,7 +30,6 @@ private: bool editInitialConditionOfSelectedRecordWithText(const char * text, bool firstInitialCondition); Shared::TextFieldDelegateApp * textFieldDelegateApp() override; Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; - Shared::InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() override; ListParameterController * parameterController() override; int maxNumberOfDisplayableRows() override; Shared::FunctionTitleCell * titleCells(int index) override; diff --git a/apps/shared/input_event_handler_delegate.h b/apps/shared/input_event_handler_delegate.h index 3fadd27fe..1382921d9 100644 --- a/apps/shared/input_event_handler_delegate.h +++ b/apps/shared/input_event_handler_delegate.h @@ -1,7 +1,6 @@ #ifndef SHARED_INPUT_EVENT_HANDLER_DELEGATE_H #define SHARED_INPUT_EVENT_HANDLER_DELEGATE_H -#include #include "input_event_handler_delegate_app.h" namespace Shared { @@ -11,7 +10,9 @@ public: Toolbox * toolboxForInputEventHandler(InputEventHandler * textInput) override { return inputEventHandlerDelegateApp()->toolboxForInputEventHandler(textInput); } NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override { return inputEventHandlerDelegateApp()->variableBoxForInputEventHandler(textInput); } private: - virtual InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() = 0; + InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() { + return static_cast(::app()); + } }; } diff --git a/apps/shared/input_event_handler_delegate_app.h b/apps/shared/input_event_handler_delegate_app.h index 3f2927c9c..0339738c0 100644 --- a/apps/shared/input_event_handler_delegate_app.h +++ b/apps/shared/input_event_handler_delegate_app.h @@ -1,7 +1,8 @@ #ifndef SHARED_INPUT_EVENT_HANDLER_DELEGATE_APP_H #define SHARED_INPUT_EVENT_HANDLER_DELEGATE_APP_H -#include +#include +#include namespace Shared { From 5058f64163983a4b90619946e535a9a445aaced6 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 17:38:01 +0200 Subject: [PATCH 063/111] [apps] Define LayoutFieldDelegate::expressionFieldDelegateApp() directly from ::app() --- apps/calculation/edit_expression_controller.cpp | 4 ---- apps/calculation/edit_expression_controller.h | 1 - apps/sequence/list/list_controller.cpp | 4 ---- apps/sequence/list/list_controller.h | 1 - apps/shared/layout_field_delegate.h | 5 +++-- apps/solver/list_controller.cpp | 4 ---- apps/solver/list_controller.h | 1 - escher/include/escher/layout_field_delegate.h | 2 +- 8 files changed, 4 insertions(+), 18 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 1111e50e4..6d5a54cc7 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -112,10 +112,6 @@ TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() { return app(); } -ExpressionFieldDelegateApp * EditExpressionController::expressionFieldDelegateApp() { - return app(); -} - void EditExpressionController::reloadView() { ((ContentView *)view())->reload(); m_historyController->reload(); diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index 1b80d8d48..565828999 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -54,7 +54,6 @@ private: bool inputViewDidFinishEditing(const char * text, Poincare::Layout layoutR); bool inputViewDidAbortEditing(const char * text); Shared::TextFieldDelegateApp * textFieldDelegateApp() override; - Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; static constexpr int k_cacheBufferSize = Constant::MaxSerializedExpressionSize; char m_cacheBuffer[k_cacheBufferSize]; HistoryController * m_historyController; diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index a884590e0..8a1dfc7ad 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -162,10 +162,6 @@ TextFieldDelegateApp * ListController::textFieldDelegateApp() { return app(); } -ExpressionFieldDelegateApp * ListController::expressionFieldDelegateApp() { - return app(); -} - ListParameterController * ListController::parameterController() { return &m_parameterController; } diff --git a/apps/sequence/list/list_controller.h b/apps/sequence/list/list_controller.h index 7d564ce9c..905b9eaef 100644 --- a/apps/sequence/list/list_controller.h +++ b/apps/sequence/list/list_controller.h @@ -29,7 +29,6 @@ private: static constexpr KDCoordinate k_expressionCellVerticalMargin = 3; bool editInitialConditionOfSelectedRecordWithText(const char * text, bool firstInitialCondition); Shared::TextFieldDelegateApp * textFieldDelegateApp() override; - Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; ListParameterController * parameterController() override; int maxNumberOfDisplayableRows() override; Shared::FunctionTitleCell * titleCells(int index) override; diff --git a/apps/shared/layout_field_delegate.h b/apps/shared/layout_field_delegate.h index 1785acca7..8caab47dc 100644 --- a/apps/shared/layout_field_delegate.h +++ b/apps/shared/layout_field_delegate.h @@ -1,7 +1,6 @@ #ifndef SHARED_LAYOUT_FIELD_DELEGATE_H #define SHARED_LAYOUT_FIELD_DELEGATE_H -#include #include "expression_field_delegate_app.h" namespace Shared { @@ -14,7 +13,9 @@ public: bool layoutFieldDidAbortEditing(LayoutField * layoutField) override; void layoutFieldDidChangeSize(LayoutField * layoutField) override; private: - virtual ExpressionFieldDelegateApp * expressionFieldDelegateApp() = 0; + ExpressionFieldDelegateApp * expressionFieldDelegateApp() { + return static_cast(::app()); + } }; } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index 6b8429713..b741ae9c2 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -232,10 +232,6 @@ Shared::TextFieldDelegateApp * ListController::textFieldDelegateApp() { return app(); } -Shared::ExpressionFieldDelegateApp * ListController::expressionFieldDelegateApp() { - return app(); -} - StackViewController * ListController::stackController() const { return static_cast(parentResponder()->parentResponder()); } diff --git a/apps/solver/list_controller.h b/apps/solver/list_controller.h index 81227ccd6..91cea7560 100644 --- a/apps/solver/list_controller.h +++ b/apps/solver/list_controller.h @@ -39,7 +39,6 @@ public: View * view() override { return &m_equationListView; } /* Text/Layout Field Delegate */ Shared::TextFieldDelegateApp * textFieldDelegateApp() override; - Shared::ExpressionFieldDelegateApp * expressionFieldDelegateApp() override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; diff --git a/escher/include/escher/layout_field_delegate.h b/escher/include/escher/layout_field_delegate.h index 2bce6a8f6..3d81702be 100644 --- a/escher/include/escher/layout_field_delegate.h +++ b/escher/include/escher/layout_field_delegate.h @@ -1,8 +1,8 @@ #ifndef ESCHER_LAYOUT_FIELD_DELEGATE_H #define ESCHER_LAYOUT_FIELD_DELEGATE_H -#include #include +#include class LayoutField; From 055d6018540aadd2a5261891a5927e4448e4a023 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 6 Jun 2019 17:50:31 +0200 Subject: [PATCH 064/111] [apps] Define TextFieldDelegate::textFieldDelegateApp() directly from ::app() --- apps/calculation/edit_expression_controller.cpp | 4 ---- apps/calculation/edit_expression_controller.h | 1 - apps/graph/list/list_controller.cpp | 4 ---- apps/graph/list/list_controller.h | 1 - apps/probability/calculation_controller.cpp | 4 ---- apps/probability/calculation_controller.h | 1 - apps/sequence/list/list_controller.cpp | 4 ---- apps/sequence/list/list_controller.h | 1 - apps/sequence/list/list_parameter_controller.cpp | 4 ---- apps/sequence/list/list_parameter_controller.h | 1 - apps/settings/sub_menu/display_mode_controller.cpp | 4 ---- apps/settings/sub_menu/display_mode_controller.h | 1 - apps/shared/editable_cell_table_view_controller.cpp | 5 ----- apps/shared/editable_cell_table_view_controller.h | 1 - apps/shared/float_parameter_controller.cpp | 5 ----- apps/shared/float_parameter_controller.h | 1 - apps/shared/go_to_parameter_controller.cpp | 1 - apps/shared/interactive_curve_view_controller.cpp | 1 - apps/shared/parameter_text_field_delegate.cpp | 5 ++--- apps/shared/parameter_text_field_delegate.h | 2 -- apps/shared/range_parameter_controller.cpp | 1 - apps/shared/simple_interactive_curve_view_controller.h | 4 ---- apps/shared/text_field_delegate.h | 7 ++++--- apps/shared/text_field_delegate_app.h | 4 +++- apps/solver/list_controller.cpp | 4 ---- apps/solver/list_controller.h | 1 - escher/include/escher/text_field_delegate.h | 2 ++ 27 files changed, 11 insertions(+), 63 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 6d5a54cc7..de82ba2d7 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -108,10 +108,6 @@ void EditExpressionController::layoutFieldDidChangeSize(::LayoutField * layoutFi } } -TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() { - return app(); -} - void EditExpressionController::reloadView() { ((ContentView *)view())->reload(); m_historyController->reload(); diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index 565828999..bf77b285d 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -53,7 +53,6 @@ private: bool inputViewDidReceiveEvent(Ion::Events::Event event, bool shouldDuplicateLastCalculation); bool inputViewDidFinishEditing(const char * text, Poincare::Layout layoutR); bool inputViewDidAbortEditing(const char * text); - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; static constexpr int k_cacheBufferSize = Constant::MaxSerializedExpressionSize; char m_cacheBuffer[k_cacheBufferSize]; HistoryController * m_historyController; diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 751634b06..5d7a26a02 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -189,8 +189,4 @@ void ListController::setFunctionNameInTextField(ExpiringPointer functi textField->setText(bufferName); } -Shared::TextFieldDelegateApp * ListController::textFieldDelegateApp() { - return app(); -} - } diff --git a/apps/graph/list/list_controller.h b/apps/graph/list/list_controller.h index a4e439b4b..72497dd1f 100644 --- a/apps/graph/list/list_controller.h +++ b/apps/graph/list/list_controller.h @@ -29,7 +29,6 @@ private: HighlightCell * expressionCells(int index) override; void willDisplayTitleCellAtIndex(HighlightCell * cell, int j) override; void willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) override; - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; void setFunctionNameInTextField(Shared::ExpiringPointer function, TextField * textField); TextFieldFunctionTitleCell m_functionTitleCells[k_maxNumberOfDisplayableRows]; Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfDisplayableRows]; diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 0ab3a4e28..91e939d2a 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -266,10 +266,6 @@ void CalculationController::setCalculationAccordingToIndex(int index, bool force m_calculation->setLaw(m_law); } -TextFieldDelegateApp * CalculationController::textFieldDelegateApp() { - return app(); -} - void CalculationController::updateTitle() { int currentChar = 0; for (int index = 0; index < m_law->numberOfParameter(); index++) { diff --git a/apps/probability/calculation_controller.h b/apps/probability/calculation_controller.h index 9aebd0410..9ace18585 100644 --- a/apps/probability/calculation_controller.h +++ b/apps/probability/calculation_controller.h @@ -47,7 +47,6 @@ public: private: constexpr static int k_numberOfCalculationCells = 3; constexpr static KDCoordinate k_tableMargin = 3; - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; void updateTitle(); class ContentView : public View { public: diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index 8a1dfc7ad..b7cf89ec3 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -158,10 +158,6 @@ bool ListController::editInitialConditionOfSelectedRecordWithText(const char * t return (error == Ion::Storage::Record::ErrorStatus::None); } -TextFieldDelegateApp * ListController::textFieldDelegateApp() { - return app(); -} - ListParameterController * ListController::parameterController() { return &m_parameterController; } diff --git a/apps/sequence/list/list_controller.h b/apps/sequence/list/list_controller.h index 905b9eaef..85f942d20 100644 --- a/apps/sequence/list/list_controller.h +++ b/apps/sequence/list/list_controller.h @@ -28,7 +28,6 @@ public: private: static constexpr KDCoordinate k_expressionCellVerticalMargin = 3; bool editInitialConditionOfSelectedRecordWithText(const char * text, bool firstInitialCondition); - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; ListParameterController * parameterController() override; int maxNumberOfDisplayableRows() override; Shared::FunctionTitleCell * titleCells(int index) override; diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 722b86041..d17d866f0 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -148,10 +148,6 @@ void ListParameterController::willDisplayCellForIndex(HighlightCell * cell, int } } -TextFieldDelegateApp * ListParameterController::textFieldDelegateApp() { - return app(); -} - int ListParameterController::totalNumberOfCells() const { if (hasInitialRankRow()) { return k_totalNumberOfCell; diff --git a/apps/sequence/list/list_parameter_controller.h b/apps/sequence/list/list_parameter_controller.h index e43ee5d43..7a6003133 100644 --- a/apps/sequence/list/list_parameter_controller.h +++ b/apps/sequence/list/list_parameter_controller.h @@ -20,7 +20,6 @@ public: bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY, bool withinTemporarySelection) override; - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; // ListViewDataSource HighlightCell * reusableCell(int index, int type) override; diff --git a/apps/settings/sub_menu/display_mode_controller.cpp b/apps/settings/sub_menu/display_mode_controller.cpp index 35b6a6fbe..8c22ca22a 100644 --- a/apps/settings/sub_menu/display_mode_controller.cpp +++ b/apps/settings/sub_menu/display_mode_controller.cpp @@ -95,8 +95,4 @@ bool DisplayModeController::textFieldDidFinishEditing(TextField * textField, con return true; } -Shared::TextFieldDelegateApp * DisplayModeController::textFieldDelegateApp() { - return app(); -} - } diff --git a/apps/settings/sub_menu/display_mode_controller.h b/apps/settings/sub_menu/display_mode_controller.h index 86ebc2098..e9bef0c2f 100644 --- a/apps/settings/sub_menu/display_mode_controller.h +++ b/apps/settings/sub_menu/display_mode_controller.h @@ -20,7 +20,6 @@ public: bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; private: - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; MessageTableCellWithEditableTextWithSeparator m_editableCell; char m_draftTextBuffer[MessageTableCellWithEditableText::k_bufferLength]; }; diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index abe82f111..2e3ba723d 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -1,7 +1,6 @@ #include "editable_cell_table_view_controller.h" #include "../shared/poincare_helpers.h" #include "../constant.h" -#include "text_field_delegate_app.h" #include #include @@ -112,8 +111,4 @@ void EditableCellTableViewController::viewWillAppear() { } } -TextFieldDelegateApp * EditableCellTableViewController::textFieldDelegateApp() { - return (TextFieldDelegateApp *)app(); -} - } diff --git a/apps/shared/editable_cell_table_view_controller.h b/apps/shared/editable_cell_table_view_controller.h index c765c61ed..f7b5900ed 100644 --- a/apps/shared/editable_cell_table_view_controller.h +++ b/apps/shared/editable_cell_table_view_controller.h @@ -23,7 +23,6 @@ public: protected: static constexpr KDCoordinate k_cellHeight = 20; private: - TextFieldDelegateApp * textFieldDelegateApp() override; virtual bool cellAtLocationIsEditable(int columnIndex, int rowIndex) = 0; virtual bool setDataAtLocation(double floatBody, int columnIndex, int rowIndex) = 0; virtual double dataAtLocation(int columnIndex, int rowIndex) = 0; diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 1bdabcc6c..540a5cece 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -1,7 +1,6 @@ #include "float_parameter_controller.h" #include "../constant.h" #include "../shared/poincare_helpers.h" -#include "text_field_delegate_app.h" #include #include @@ -138,10 +137,6 @@ bool FloatParameterController::textFieldDidFinishEditing(TextField * textField, return true; } -TextFieldDelegateApp * FloatParameterController::textFieldDelegateApp() { - return (TextFieldDelegateApp *)app(); -} - int FloatParameterController::activeCell() { return selectedRow(); } diff --git a/apps/shared/float_parameter_controller.h b/apps/shared/float_parameter_controller.h index 4a8060ae6..2ed08719f 100644 --- a/apps/shared/float_parameter_controller.h +++ b/apps/shared/float_parameter_controller.h @@ -39,7 +39,6 @@ private: virtual void buttonAction(); virtual int reusableParameterCellCount(int type) = 0; virtual HighlightCell * reusableParameterCell(int index, int type) = 0; - TextFieldDelegateApp * textFieldDelegateApp() override; virtual bool setParameterAtIndex(int parameterIndex, double f) = 0; }; diff --git a/apps/shared/go_to_parameter_controller.cpp b/apps/shared/go_to_parameter_controller.cpp index 732799e70..c72669e8e 100644 --- a/apps/shared/go_to_parameter_controller.cpp +++ b/apps/shared/go_to_parameter_controller.cpp @@ -1,5 +1,4 @@ #include "go_to_parameter_controller.h" -#include "text_field_delegate_app.h" #include namespace Shared { diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index 4d3b98409..c7ba92d93 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -1,5 +1,4 @@ #include "interactive_curve_view_controller.h" -#include "text_field_delegate_app.h" #include #include #include diff --git a/apps/shared/parameter_text_field_delegate.cpp b/apps/shared/parameter_text_field_delegate.cpp index 65aaed12e..990a0e692 100644 --- a/apps/shared/parameter_text_field_delegate.cpp +++ b/apps/shared/parameter_text_field_delegate.cpp @@ -1,10 +1,9 @@ #include "parameter_text_field_delegate.h" - -using namespace Poincare; +#include namespace Shared { -bool ParameterTextFieldDelegate::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) { +bool ParameterTextFieldDelegate::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { if (event == Ion::Events::Backspace && !textField->isEditing()) { textField->setEditing(true); return true; diff --git a/apps/shared/parameter_text_field_delegate.h b/apps/shared/parameter_text_field_delegate.h index 80f420ce3..195dc817c 100644 --- a/apps/shared/parameter_text_field_delegate.h +++ b/apps/shared/parameter_text_field_delegate.h @@ -1,9 +1,7 @@ #ifndef SHARED_PARAMETER_TEXT_FIELD_DELEGATE_H #define SHARED_PARAMETER_TEXT_FIELD_DELEGATE_H -#include #include "text_field_delegate.h" -#include "text_field_delegate_app.h" namespace Shared { diff --git a/apps/shared/range_parameter_controller.cpp b/apps/shared/range_parameter_controller.cpp index 4fb1806f1..3c169d7c4 100644 --- a/apps/shared/range_parameter_controller.cpp +++ b/apps/shared/range_parameter_controller.cpp @@ -1,5 +1,4 @@ #include "range_parameter_controller.h" -#include "text_field_delegate_app.h" #include using namespace Poincare; diff --git a/apps/shared/simple_interactive_curve_view_controller.h b/apps/shared/simple_interactive_curve_view_controller.h index 6a1750d82..16eb6d627 100644 --- a/apps/shared/simple_interactive_curve_view_controller.h +++ b/apps/shared/simple_interactive_curve_view_controller.h @@ -2,7 +2,6 @@ #define SHARED_SIMPLE_INTERACTIVE_CURVE_VIEW_CONTROLLER_H #include -#include #include "text_field_delegate.h" #include "interactive_curve_view_range.h" #include "curve_view_cursor.h" @@ -21,9 +20,6 @@ public: bool textFieldDidAbortEditing(TextField * textField) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; protected: - TextFieldDelegateApp * textFieldDelegateApp() override { - return static_cast(app()); - } constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth virtual float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2)/graphViewHeight diff --git a/apps/shared/text_field_delegate.h b/apps/shared/text_field_delegate.h index c23a0ad0e..3d12bca36 100644 --- a/apps/shared/text_field_delegate.h +++ b/apps/shared/text_field_delegate.h @@ -1,7 +1,6 @@ #ifndef SHARED_TEXT_FIELD_DELEGATE_H #define SHARED_TEXT_FIELD_DELEGATE_H -#include #include "text_field_delegate_app.h" namespace Shared { @@ -10,8 +9,10 @@ class TextFieldDelegate : public ::TextFieldDelegate { public: bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; -private: - virtual TextFieldDelegateApp * textFieldDelegateApp() = 0; +protected: + TextFieldDelegateApp * textFieldDelegateApp() { + return static_cast(::app()); + } }; } diff --git a/apps/shared/text_field_delegate_app.h b/apps/shared/text_field_delegate_app.h index c9f96b29c..7b9ba14ab 100644 --- a/apps/shared/text_field_delegate_app.h +++ b/apps/shared/text_field_delegate_app.h @@ -2,10 +2,12 @@ #define SHARED_TEXT_FIELD_DELEGATE_APP_H #include -#include #include "input_event_handler_delegate_app.h" +#include #include +class EditableField; + namespace Shared { class TextFieldDelegateApp : public InputEventHandlerDelegateApp, public TextFieldDelegate { diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index b741ae9c2..c0ef1956d 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -228,10 +228,6 @@ SelectableTableView * ListController::selectableTableView() { return m_equationListView.selectableTableView(); } -Shared::TextFieldDelegateApp * ListController::textFieldDelegateApp() { - return app(); -} - StackViewController * ListController::stackController() const { return static_cast(parentResponder()->parentResponder()); } diff --git a/apps/solver/list_controller.h b/apps/solver/list_controller.h index 91cea7560..5d54369e0 100644 --- a/apps/solver/list_controller.h +++ b/apps/solver/list_controller.h @@ -38,7 +38,6 @@ public: /* ViewController */ View * view() override { return &m_equationListView; } /* Text/Layout Field Delegate */ - Shared::TextFieldDelegateApp * textFieldDelegateApp() override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; bool layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion::Events::Event event) override; bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; diff --git a/escher/include/escher/text_field_delegate.h b/escher/include/escher/text_field_delegate.h index 0fae1bc21..4be1741e6 100644 --- a/escher/include/escher/text_field_delegate.h +++ b/escher/include/escher/text_field_delegate.h @@ -1,6 +1,8 @@ #ifndef ESCHER_TEXT_FIELD_DELEGATE_H #define ESCHER_TEXT_FIELD_DELEGATE_H +#include + class TextField; class TextFieldDelegate { From e9d098bacbff7182ba503bac2fae357fd864f894 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 16 Jul 2019 18:02:59 +0200 Subject: [PATCH 065/111] [apps] Remove AppsContainerStorage::sharedContainer Use AppsContainer::sharedAppsContainer instead. The AppsContainerStorage is initialised in AppsContainer. --- apps/Makefile | 2 +- apps/apps_container.cpp | 6 ++++++ apps/apps_container.h | 4 +--- apps/apps_container_storage.cpp | 5 ----- apps/apps_container_storage.h | 1 - apps/main.cpp | 8 ++++---- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/apps/Makefile b/apps/Makefile index 34eeb7463..beb157545 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -38,7 +38,7 @@ snapshots_count = $(words $(apps)) snapshot_includes = $(foreach i,$(app_headers),-include $(i) ) epsilon_app_names = '$(foreach i,${EPSILON_APPS},"$(i)", )' -$(call object_for,apps/apps_container_storage.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) +$(call object_for,apps/apps_container_storage.cpp apps/apps_container.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) # I18n file generation diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index 76ca26097..5682399f7 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -1,4 +1,5 @@ #include "apps_container.h" +#include "apps_container_storage.h" #include "global_preferences.h" #include #include @@ -52,6 +53,11 @@ static KDColor sPromptColors[] = { #endif +AppsContainer * AppsContainer::sharedAppsContainer() { + static AppsContainerStorage appsContainerStorage; + return &appsContainerStorage; +} + AppsContainer::AppsContainer() : Container(), m_window(), diff --git a/apps/apps_container.h b/apps/apps_container.h index c8236271b..dca1a48bb 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -24,9 +24,7 @@ class AppsContainer : public Container, ExamPopUpControllerDelegate, Ion::StorageDelegate { public: - static AppsContainer * sharedAppsContainer() { - return static_cast(Container::sharedContainer()); - } + static AppsContainer * sharedAppsContainer(); AppsContainer(); static bool poincareCircuitBreaker(); virtual int numberOfApps() = 0; diff --git a/apps/apps_container_storage.cpp b/apps/apps_container_storage.cpp index 57b1d24d9..2ef60aafa 100644 --- a/apps/apps_container_storage.cpp +++ b/apps/apps_container_storage.cpp @@ -14,11 +14,6 @@ constexpr int k_numberOfCommonApps = 1+APPS_CONTAINER_SNAPSHOT_COUNT; // Take the Home app into account -AppsContainerStorage * AppsContainerStorage::sharedContainer() { - static AppsContainerStorage appsContainerStorage; - return &appsContainerStorage; -} - AppsContainerStorage::AppsContainerStorage() : AppsContainer() APPS_CONTAINER_SNAPSHOT_CONSTRUCTORS diff --git a/apps/apps_container_storage.h b/apps/apps_container_storage.h index e726b1161..9abd3c27a 100644 --- a/apps/apps_container_storage.h +++ b/apps/apps_container_storage.h @@ -9,7 +9,6 @@ class AppsContainerStorage : public AppsContainer { public: - static AppsContainerStorage * sharedContainer(); AppsContainerStorage(); int numberOfApps() override; App::Snapshot * appSnapshotAtIndex(int index) override; diff --git a/apps/main.cpp b/apps/main.cpp index fb2c90dc1..8fb2dc470 100644 --- a/apps/main.cpp +++ b/apps/main.cpp @@ -1,4 +1,4 @@ -#include "apps_container_storage.h" +#include "apps_container.h" #include "global_preferences.h" #include @@ -32,8 +32,8 @@ void ion_main(int argc, char * argv[]) { * $ ./epsilon.elf --code-script hello_world.py:print("hello") --code-lock-on-console */ const char * appNames[] = {"home", EPSILON_APPS_NAMES}; - for (int j = 0; j < AppsContainerStorage::sharedContainer()->numberOfApps(); j++) { - App::Snapshot * snapshot = AppsContainerStorage::sharedContainer()->appSnapshotAtIndex(j); + for (int j = 0; j < AppsContainer::sharedAppsContainer()->numberOfApps(); j++) { + App::Snapshot * snapshot = AppsContainer::sharedAppsContainer()->appSnapshotAtIndex(j); int cmp = strcmp(argv[i]+2, appNames[j]); if (cmp == '-') { snapshot->setOpt(argv[i]+2+strlen(appNames[j])+1, argv[i+1]); @@ -42,5 +42,5 @@ void ion_main(int argc, char * argv[]) { } } #endif - AppsContainerStorage::sharedContainer()->run(); + AppsContainer::sharedAppsContainer()->run(); } From 1dd39f6f6bb90e7a8041d238873a4974da89ae7c Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 10:03:43 +0200 Subject: [PATCH 066/111] [apps/home] Revert commit "Select cell on Snapshot's construction" --- apps/home/app.h | 1 - apps/home/controller.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/home/app.h b/apps/home/app.h index 16335ad97..d483c89e3 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -15,7 +15,6 @@ public: }; class Snapshot : public ::App::Snapshot, public SelectableTableViewDataSource { public: - Snapshot() { selectCellAtLocation(0, 0); } App * unpack(Container * container) override; Descriptor * descriptor() override; }; diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 2d98b6f88..238aa0b35 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -78,6 +78,9 @@ bool Controller::handleEvent(Ion::Events::Event event) { } void Controller::didBecomeFirstResponder() { + if (selectionDataSource()->selectedRow() == -1) { + selectionDataSource()->selectCellAtLocation(0, 0); + } app()->setFirstResponder(m_view.selectableTableView()); } From 0531187cda65ff83b572eda4eca7c416e4ddb8df Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 10:56:32 +0200 Subject: [PATCH 067/111] [escher] Cleaner app header inclusion --- escher/include/escher/selectable_table_view.h | 1 - escher/src/nested_menu_controller.cpp | 1 + escher/src/selectable_table_view.cpp | 1 + 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/escher/include/escher/selectable_table_view.h b/escher/include/escher/selectable_table_view.h index cecd44a74..462041a37 100644 --- a/escher/include/escher/selectable_table_view.h +++ b/escher/include/escher/selectable_table_view.h @@ -2,7 +2,6 @@ #define ESCHER_SELECTABLE_TABLE_VIEW_H #include -#include #include #include #include diff --git a/escher/src/nested_menu_controller.cpp b/escher/src/nested_menu_controller.cpp index e19708512..01e1dc9af 100644 --- a/escher/src/nested_menu_controller.cpp +++ b/escher/src/nested_menu_controller.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index 226701a6d..d525889b3 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include From 17795eed87379c8d6e1d1359527fbb12c242f5dd Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 11:04:49 +0200 Subject: [PATCH 068/111] [escher] Include container.h instead of app.h app.h did actually include container.h --- escher/include/escher.h | 1 - escher/include/escher/app.h | 3 --- escher/src/alternate_empty_view_controller.cpp | 2 +- escher/src/bank_view_controller.cpp | 2 +- escher/src/button_row_controller.cpp | 2 +- escher/src/editable_text_cell.cpp | 2 +- escher/src/even_odd_editable_text_cell.cpp | 2 +- escher/src/input_event_handler.cpp | 2 +- escher/src/input_view_controller.cpp | 2 +- escher/src/message_table_cell_with_editable_text.cpp | 2 +- escher/src/modal_view_controller.cpp | 2 +- escher/src/nested_menu_controller.cpp | 2 +- escher/src/selectable_table_view.cpp | 2 +- escher/src/stack_view_controller.cpp | 2 +- escher/src/tab_view_controller.cpp | 2 +- escher/src/warning_controller.cpp | 2 +- 16 files changed, 14 insertions(+), 18 deletions(-) diff --git a/escher/include/escher.h b/escher/include/escher.h index f1b8736fb..d0926e8cb 100644 --- a/escher/include/escher.h +++ b/escher/include/escher.h @@ -3,7 +3,6 @@ #include #include -#include #include #include #include diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index c4ad4d5ad..18e7e76a9 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -72,8 +72,5 @@ private: WarningController m_warningController; }; -// Make sure App * app() is reachable by anyone including only app.h -#include - #endif diff --git a/escher/src/alternate_empty_view_controller.cpp b/escher/src/alternate_empty_view_controller.cpp index 43159799e..75314077e 100644 --- a/escher/src/alternate_empty_view_controller.cpp +++ b/escher/src/alternate_empty_view_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include /* ContentView */ diff --git a/escher/src/bank_view_controller.cpp b/escher/src/bank_view_controller.cpp index 315088247..71f26468b 100644 --- a/escher/src/bank_view_controller.cpp +++ b/escher/src/bank_view_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include BankViewController::BankViewController(Responder * parentViewController) : ViewController(parentViewController), diff --git a/escher/src/button_row_controller.cpp b/escher/src/button_row_controller.cpp index a010d054d..6139c08a2 100644 --- a/escher/src/button_row_controller.cpp +++ b/escher/src/button_row_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/escher/src/editable_text_cell.cpp b/escher/src/editable_text_cell.cpp index f6388bfb0..b03d6bed7 100644 --- a/escher/src/editable_text_cell.cpp +++ b/escher/src/editable_text_cell.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/escher/src/even_odd_editable_text_cell.cpp b/escher/src/even_odd_editable_text_cell.cpp index 2eb3bbc63..00473c504 100644 --- a/escher/src/even_odd_editable_text_cell.cpp +++ b/escher/src/even_odd_editable_text_cell.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include EvenOddEditableTextCell::EvenOddEditableTextCell(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate, char * draftTextBuffer, const KDFont * font, float horizontalAlignment, float verticalAlignment, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) : diff --git a/escher/src/input_event_handler.cpp b/escher/src/input_event_handler.cpp index c99fc6524..8d197fb39 100644 --- a/escher/src/input_event_handler.cpp +++ b/escher/src/input_event_handler.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index c9e4fac94..8aeccdf25 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/escher/src/message_table_cell_with_editable_text.cpp b/escher/src/message_table_cell_with_editable_text.cpp index a9d2909fb..401ab0084 100644 --- a/escher/src/message_table_cell_with_editable_text.cpp +++ b/escher/src/message_table_cell_with_editable_text.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include MessageTableCellWithEditableText::MessageTableCellWithEditableText(Responder * parentResponder, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, char * draftTextBuffer, I18n::Message message) : Responder(parentResponder), diff --git a/escher/src/modal_view_controller.cpp b/escher/src/modal_view_controller.cpp index 316a85c26..5b35e1ab3 100644 --- a/escher/src/modal_view_controller.cpp +++ b/escher/src/modal_view_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include ModalViewController::ContentView::ContentView() : diff --git a/escher/src/nested_menu_controller.cpp b/escher/src/nested_menu_controller.cpp index 01e1dc9af..afac10050 100644 --- a/escher/src/nested_menu_controller.cpp +++ b/escher/src/nested_menu_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index d525889b3..d5c6005b8 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/escher/src/stack_view_controller.cpp b/escher/src/stack_view_controller.cpp index 795a5ee3a..0facbf629 100644 --- a/escher/src/stack_view_controller.cpp +++ b/escher/src/stack_view_controller.cpp @@ -2,7 +2,7 @@ extern "C" { #include } #include -#include +#include #include StackViewController::ControllerView::ControllerView() : diff --git a/escher/src/tab_view_controller.cpp b/escher/src/tab_view_controller.cpp index 098663bc7..7c09780d2 100644 --- a/escher/src/tab_view_controller.cpp +++ b/escher/src/tab_view_controller.cpp @@ -3,7 +3,7 @@ extern "C" { } #include #include -#include +#include TabViewController::ContentView::ContentView() : View(), diff --git a/escher/src/warning_controller.cpp b/escher/src/warning_controller.cpp index bbb5cf098..1030d922d 100644 --- a/escher/src/warning_controller.cpp +++ b/escher/src/warning_controller.cpp @@ -1,5 +1,5 @@ #include -#include +#include static inline KDCoordinate maxCoordinate(KDCoordinate x, KDCoordinate y) { return x > y ? x : y; } From 80981ce865e1ccbab2d222dbca6080d52c4bb521 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 14:50:39 +0200 Subject: [PATCH 069/111] [escher/container] Make activeApp static --- escher/include/escher/container.h | 4 ++-- escher/src/container.cpp | 36 +++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 9d70aa331..93bb3eafa 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -17,6 +17,7 @@ class Container : public RunLoop { public: + static App * activeApp() { return s_activeApp; } static Container * sharedContainer() { assert(s_sharedContainer); return s_sharedContainer; @@ -29,7 +30,6 @@ public: Container& operator=(Container&& other) = delete; virtual void * currentAppBuffer() = 0; virtual void run(); - App * activeApp() { return m_activeApp; } virtual bool dispatchEvent(Ion::Events::Event event) override; virtual bool switchTo(App::Snapshot * snapshot); protected: @@ -43,7 +43,7 @@ private: Timer * timerAtIndex(int i) override; virtual int numberOfContainerTimers(); virtual Timer * containerTimerAtIndex(int i); - App * m_activeApp; + static App * s_activeApp; static Container * s_sharedContainer; }; diff --git a/escher/src/container.cpp b/escher/src/container.cpp index 5bed9f494..45791bfc6 100644 --- a/escher/src/container.cpp +++ b/escher/src/container.cpp @@ -2,39 +2,39 @@ #include Container::Container() : - RunLoop(), - m_activeApp(nullptr) + RunLoop() { } // Initialize private static member +App * Container::s_activeApp = nullptr; Container * Container::s_sharedContainer = nullptr; Container::~Container() { - if (m_activeApp) { - m_activeApp->~App(); + if (s_activeApp) { + s_activeApp->~App(); } } bool Container::switchTo(App::Snapshot * snapshot) { - if (m_activeApp && snapshot == m_activeApp->snapshot()) { + if (s_activeApp && snapshot == s_activeApp->snapshot()) { return true; } - if (m_activeApp && !m_activeApp->prepareForExit()) { + if (s_activeApp && !s_activeApp->prepareForExit()) { /* activeApp()->prepareForExit() returned false, which means that the app * needs another event loop to prepare for being switched off. */ return false; } - if (m_activeApp) { - m_activeApp->willBecomeInactive(); - m_activeApp->snapshot()->pack(m_activeApp); - m_activeApp = nullptr; + if (s_activeApp) { + s_activeApp->willBecomeInactive(); + s_activeApp->snapshot()->pack(s_activeApp); + s_activeApp = nullptr; } if (snapshot) { - m_activeApp = snapshot->unpack(this); + s_activeApp = snapshot->unpack(this); } - if (m_activeApp) { - m_activeApp->didBecomeActive(window()); + if (s_activeApp) { + s_activeApp->didBecomeActive(window()); window()->redraw(); } return true; @@ -45,7 +45,7 @@ bool Container::dispatchEvent(Ion::Events::Event event) { window()->redraw(); return true; } - if (m_activeApp->processEvent(event)) { + if (s_activeApp->processEvent(event)) { window()->redraw(); return true; } @@ -58,14 +58,14 @@ void Container::run() { } int Container::numberOfTimers() { - return m_activeApp->numberOfTimers() + numberOfContainerTimers(); + return s_activeApp->numberOfTimers() + numberOfContainerTimers(); } Timer * Container::timerAtIndex(int i) { - if (i < m_activeApp->numberOfTimers()) { - return m_activeApp->timerAtIndex(i); + if (i < s_activeApp->numberOfTimers()) { + return s_activeApp->timerAtIndex(i); } - return containerTimerAtIndex(i-m_activeApp->numberOfTimers()); + return containerTimerAtIndex(i-s_activeApp->numberOfTimers()); } int Container::numberOfContainerTimers() { From a0e6151b26a602a9c8f0e6640521cc201c1c2319 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 15:36:43 +0200 Subject: [PATCH 070/111] [*container] Remove static Container::sharedContainer --- apps/apps_container.cpp | 1 - escher/include/escher/container.h | 10 +--------- escher/src/container.cpp | 1 - 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index 5682399f7..b1caa6a0a 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -247,7 +247,6 @@ bool AppsContainer::switchTo(App::Snapshot * snapshot) { } void AppsContainer::run() { - setSharedContainer(this); window()->setFrame(KDRect(0, 0, Ion::Display::Width, Ion::Display::Height)); refreshPreferences(); diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 93bb3eafa..eea917b01 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -18,10 +18,6 @@ class Container : public RunLoop { public: static App * activeApp() { return s_activeApp; } - static Container * sharedContainer() { - assert(s_sharedContainer); - return s_sharedContainer; - } Container(); virtual ~Container(); Container(const Container& other) = delete; @@ -34,9 +30,6 @@ public: virtual bool switchTo(App::Snapshot * snapshot); protected: virtual Window * window() = 0; - void setSharedContainer(Container * container) { - s_sharedContainer = container; - } private: void step(); int numberOfTimers() override; @@ -44,11 +37,10 @@ private: virtual int numberOfContainerTimers(); virtual Timer * containerTimerAtIndex(int i); static App * s_activeApp; - static Container * s_sharedContainer; }; inline App * app() { - return Container::sharedContainer()->activeApp(); + return Container::activeApp(); } #endif diff --git a/escher/src/container.cpp b/escher/src/container.cpp index 45791bfc6..a307e4cfc 100644 --- a/escher/src/container.cpp +++ b/escher/src/container.cpp @@ -8,7 +8,6 @@ Container::Container() : // Initialize private static member App * Container::s_activeApp = nullptr; -Container * Container::s_sharedContainer = nullptr; Container::~Container() { if (s_activeApp) { From 224f7873f7b0dba4a7d53801f117bafd7ef0f94d Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 15:44:09 +0200 Subject: [PATCH 071/111] [*container] Make Container::s_activeApp protected --- apps/apps_container.cpp | 26 +++++++++++++------------- escher/include/escher/container.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index b1caa6a0a..2fa70db8b 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -138,8 +138,8 @@ void AppsContainer::suspend(bool checkIfPowerKeyReleased) { resetShiftAlphaStatus(); GlobalPreferences * globalPreferences = GlobalPreferences::sharedGlobalPreferences(); #ifdef EPSILON_BOOT_PROMPT - if (activeApp()->snapshot()!= onBoardingAppSnapshot() && activeApp()->snapshot() != hardwareTestAppSnapshot() && globalPreferences->showPopUp()) { - activeApp()->displayModalViewController(&m_promptController, 0.f, 0.f); + if (s_activeApp->snapshot()!= onBoardingAppSnapshot() && s_activeApp->snapshot() != hardwareTestAppSnapshot() && globalPreferences->showPopUp()) { + s_activeApp->displayModalViewController(&m_promptController, 0.f, 0.f); } #endif Ion::Power::suspend(checkIfPowerKeyReleased); @@ -157,7 +157,7 @@ bool AppsContainer::dispatchEvent(Ion::Events::Event event) { if (event == Ion::Events::USBEnumeration) { if (Ion::USB::isPlugged()) { - App::Snapshot * activeSnapshot = (activeApp() == nullptr ? appSnapshotAtIndex(0) : activeApp()->snapshot()); + App::Snapshot * activeSnapshot = (s_activeApp == nullptr ? appSnapshotAtIndex(0) : s_activeApp->snapshot()); /* Just after a software update, the battery timer does not have time to * fire before the calculator enters DFU mode. As the DFU mode blocks the * event loop, we update the battery state "manually" here. @@ -232,7 +232,7 @@ bool AppsContainer::processEvent(Ion::Events::Event event) { } bool AppsContainer::switchTo(App::Snapshot * snapshot) { - if (activeApp() && snapshot != activeApp()->snapshot()) { + if (s_activeApp && snapshot != s_activeApp->snapshot()) { resetShiftAlphaStatus(); } if (snapshot == hardwareTestAppSnapshot() || snapshot == onBoardingAppSnapshot()) { @@ -270,11 +270,11 @@ void AppsContainer::run() { (void) switched; // Silence compilation warning about unused variable. } else { // Exception - if (activeApp() != nullptr) { + if (s_activeApp != nullptr) { /* The app models can reference layouts or expressions that have been * destroyed from the pool. To avoid using them before packing the app * (in App::willBecomeInactive for instance), we tidy them early on. */ - activeApp()->snapshot()->tidy(); + s_activeApp->snapshot()->tidy(); /* When an app encoutered an exception due to a full pool, the next time * the user enters the app, the same exception could happen again which * would prevent from reopening the app. To avoid being stuck outside the @@ -282,13 +282,13 @@ void AppsContainer::run() { * exception. For instance, the calculation app can encounter an * exception when displaying too many huge layouts, if we don't clean the * history here, we will be stuck outside the calculation app. */ - activeApp()->snapshot()->reset(); + s_activeApp->snapshot()->reset(); } bool switched = switchTo(appSnapshotAtIndex(0)); assert(switched); (void) switched; // Silence compilation warning about unused variable. Poincare::Tidy(); - activeApp()->displayWarning(I18n::Message::PoolMemoryFull1, I18n::Message::PoolMemoryFull2, true); + s_activeApp->displayWarning(I18n::Message::PoolMemoryFull1, I18n::Message::PoolMemoryFull2, true); } Container::run(); switchTo(nullptr); @@ -314,7 +314,7 @@ void AppsContainer::reloadTitleBarView() { void AppsContainer::displayExamModePopUp(bool activate) { m_examPopUpController.setActivatingExamMode(activate); - activeApp()->displayModalViewController(&m_examPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin); + s_activeApp->displayModalViewController(&m_examPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin); } void AppsContainer::shutdownDueToLowBattery() { @@ -361,14 +361,14 @@ void AppsContainer::examDeactivatingPopUpIsDismissed() { } void AppsContainer::storageDidChangeForRecord(const Ion::Storage::Record record) { - if (activeApp()) { - activeApp()->snapshot()->storageDidChangeForRecord(record); + if (s_activeApp) { + s_activeApp->snapshot()->storageDidChangeForRecord(record); } } void AppsContainer::storageIsFull() { - if (activeApp()) { - activeApp()->displayWarning(I18n::Message::StorageMemoryFull1, I18n::Message::StorageMemoryFull2, true); + if (s_activeApp) { + s_activeApp->displayWarning(I18n::Message::StorageMemoryFull1, I18n::Message::StorageMemoryFull2, true); } } diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index eea917b01..1b2bacd8b 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -30,13 +30,13 @@ public: virtual bool switchTo(App::Snapshot * snapshot); protected: virtual Window * window() = 0; + static App * s_activeApp; private: void step(); int numberOfTimers() override; Timer * timerAtIndex(int i) override; virtual int numberOfContainerTimers(); virtual Timer * containerTimerAtIndex(int i); - static App * s_activeApp; }; inline App * app() { From 772610d9e055ddcc88145183771899fcbf14d56e Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 17 Jul 2019 15:45:51 +0200 Subject: [PATCH 072/111] [escher/container] Assert activeApp() does not return nullptr --- escher/include/escher/container.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 1b2bacd8b..773191188 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -17,7 +17,10 @@ class Container : public RunLoop { public: - static App * activeApp() { return s_activeApp; } + static App * activeApp() { + assert(s_activeApp); + return s_activeApp; + } Container(); virtual ~Container(); Container(const Container& other) = delete; From b4cac92af20024655ca75117149c07754305ff01 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 15:37:37 +0200 Subject: [PATCH 073/111] [escher/modal_view_controller] Clean didBecomeFirstResponder --- escher/src/modal_view_controller.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/escher/src/modal_view_controller.cpp b/escher/src/modal_view_controller.cpp index 5b35e1ab3..893abd648 100644 --- a/escher/src/modal_view_controller.cpp +++ b/escher/src/modal_view_controller.cpp @@ -136,9 +136,6 @@ void ModalViewController::dismissModalViewController() { } void ModalViewController::didBecomeFirstResponder() { - if (m_contentView.isDisplayingModal()) { - app()->setFirstResponder(m_currentModalViewController); - } app()->setFirstResponder(m_regularViewController); } From 14835d0454aacf2a20c132dea6c56ee7f796a8d2 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 17:00:05 +0200 Subject: [PATCH 074/111] [apps/exam_pop_up_controller] ContentView accesses the app directly --- apps/exam_pop_up_controller.cpp | 14 +++++--------- apps/exam_pop_up_controller.h | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/exam_pop_up_controller.cpp b/apps/exam_pop_up_controller.cpp index a4568833b..94d06c41c 100644 --- a/apps/exam_pop_up_controller.cpp +++ b/apps/exam_pop_up_controller.cpp @@ -30,16 +30,16 @@ void ExamPopUpController::viewDidDisappear() { } void ExamPopUpController::didBecomeFirstResponder() { - m_contentView.setSelectedButton(0, app()); + m_contentView.setSelectedButton(0); } bool ExamPopUpController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Left && m_contentView.selectedButton() == 1) { - m_contentView.setSelectedButton(0, app()); + m_contentView.setSelectedButton(0); return true; } if (event == Ion::Events::Right && m_contentView.selectedButton() == 0) { - m_contentView.setSelectedButton(1, app()); + m_contentView.setSelectedButton(1); return true; } return false; @@ -78,14 +78,10 @@ void ExamPopUpController::ContentView::drawRect(KDContext * ctx, KDRect rect) co ctx->fillRect(bounds(), KDColorBlack); } -void ExamPopUpController::ContentView::setSelectedButton(int selectedButton, App * app) { +void ExamPopUpController::ContentView::setSelectedButton(int selectedButton) { m_cancelButton.setHighlighted(selectedButton == 0); m_okButton.setHighlighted(selectedButton == 1); - if (selectedButton == 0) { - app->setFirstResponder(&m_cancelButton); - } else { - app->setFirstResponder(&m_okButton); - } + app()->setFirstResponder(selectedButton == 0 ? &m_cancelButton : &m_okButton); } int ExamPopUpController::ContentView::selectedButton() { diff --git a/apps/exam_pop_up_controller.h b/apps/exam_pop_up_controller.h index fd04f50dc..ad888cff9 100644 --- a/apps/exam_pop_up_controller.h +++ b/apps/exam_pop_up_controller.h @@ -26,7 +26,7 @@ private: public: ContentView(Responder * parentResponder); void drawRect(KDContext * ctx, KDRect rect) const override; - void setSelectedButton(int selectedButton, App * app); + void setSelectedButton(int selectedButton); int selectedButton(); void setMessages(bool activingExamMode); private: From 2c9489966de3f304d0e4e7cf037fd1c18228e6fc Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 17:31:53 +0200 Subject: [PATCH 075/111] [apps/graph/graph] GraphController accesses the app directly --- apps/graph/graph/graph_controller.cpp | 4 ++-- apps/graph/graph/graph_controller_helper.cpp | 12 ++++++------ apps/graph/graph/graph_controller_helper.h | 4 ++-- apps/graph/graph/tangent_graph_controller.cpp | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index b07587948..30171637f 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -73,12 +73,12 @@ void GraphController::reloadBannerView() { return; } Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()); - reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, record, app()); + reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, record); } bool GraphController::moveCursorHorizontally(int direction) { Ion::Storage::Record record = functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor()); - return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, record, app()); + return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, record); } InteractiveCurveViewRange * GraphController::interactiveCurveViewRange() { diff --git a/apps/graph/graph/graph_controller_helper.cpp b/apps/graph/graph/graph_controller_helper.cpp index 00adae62c..ad4f18a2a 100644 --- a/apps/graph/graph/graph_controller_helper.cpp +++ b/apps/graph/graph/graph_controller_helper.cpp @@ -9,24 +9,24 @@ using namespace Poincare; namespace Graph { -bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record, App * app) { - ExpiringPointer function = app->functionStore()->modelForRecord(record); +bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record) { + ExpiringPointer function = app()->functionStore()->modelForRecord(record); double xCursorPosition = cursor->x(); double x = direction > 0 ? xCursorPosition + range->xGridUnit()/numberOfStepsInGradUnit : xCursorPosition - range->xGridUnit()/numberOfStepsInGradUnit; - double y = function->evaluateAtAbscissa(x, app->localContext()); + double y = function->evaluateAtAbscissa(x, app()->localContext()); cursor->moveTo(x, y); return true; } -void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record, App * app) { - ExpiringPointer function = app->functionStore()->modelForRecord(record); +void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) { + ExpiringPointer function = app()->functionStore()->modelForRecord(record); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * space = " "; int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize, CartesianFunction::Symbol()); const char * legend = "="; numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar); - double y = function->approximateDerivative(cursor->x(), app->localContext()); + double y = function->approximateDerivative(cursor->x(), app()->localContext()); numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize-numberOfChar, Constant::ShortNumberOfSignificantDigits); strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar); bannerView()->derivativeView()->setText(buffer); diff --git a/apps/graph/graph/graph_controller_helper.h b/apps/graph/graph/graph_controller_helper.h index 811a99f79..9b0ecedf7 100644 --- a/apps/graph/graph/graph_controller_helper.h +++ b/apps/graph/graph/graph_controller_helper.h @@ -11,8 +11,8 @@ class App; class GraphControllerHelper { protected: - bool privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record, App * app); - void reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record, App * app); + bool privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record); + void reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record); virtual BannerView * bannerView() = 0; }; diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 46b61eb1c..c7af689c6 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -62,7 +62,7 @@ void TangentGraphController::reloadBannerView() { return; } FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, app()->functionStore(), CartesianFunction::Symbol()); - GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record, app()); + GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * legend = "a="; @@ -81,7 +81,7 @@ void TangentGraphController::reloadBannerView() { } bool TangentGraphController::moveCursorHorizontally(int direction) { - return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_record, app()); + return privateMoveCursorHorizontally(m_cursor, direction, m_graphRange, k_numberOfCursorStepsInGradUnit, m_record); } bool TangentGraphController::handleEnter() { From ff887ec4a0e945d81acb9d1acdaf7b0267b097d5 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 17:48:27 +0200 Subject: [PATCH 076/111] [apps/shared] Define static app() accessor in FunctionApp class --- apps/graph/graph/tangent_graph_controller.cpp | 2 +- apps/sequence/list/list_controller.cpp | 2 +- apps/shared/function_app.h | 5 ++++- apps/shared/function_go_to_parameter_controller.cpp | 2 +- apps/shared/function_graph_controller.cpp | 3 +-- apps/shared/function_list_controller.cpp | 6 ++---- apps/shared/list_parameter_controller.cpp | 3 +-- apps/shared/sum_graph_controller.cpp | 4 ++-- apps/shared/values_controller.cpp | 3 +-- apps/shared/values_function_parameter_controller.cpp | 3 +-- 10 files changed, 15 insertions(+), 18 deletions(-) diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index c7af689c6..4c7808c8b 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -61,7 +61,7 @@ void TangentGraphController::reloadBannerView() { if (m_record.isNull()) { return; } - FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, app()->functionStore(), CartesianFunction::Symbol()); + FunctionBannerDelegate::reloadBannerViewForCursorOnFunction(m_cursor, m_record, Shared::FunctionApp::app()->functionStore(), CartesianFunction::Symbol()); GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index b7cf89ec3..dad72cdd7 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -107,7 +107,7 @@ void ListController::editExpression(int sequenceDefinition, Ion::Events::Event e // Replace UCodePointUnknownN with 'n' replaceUnknownSymbolWithReadableSymbol(initialText); } - InputViewController * inputController = app()->inputViewController(); + InputViewController * inputController = Shared::FunctionApp::app()->inputViewController(); // Invalidate the sequences context cache app()->localContext()->resetCache(); switch (sequenceDefinition) { diff --git a/apps/shared/function_app.h b/apps/shared/function_app.h index 687e6185a..932ed30dd 100644 --- a/apps/shared/function_app.h +++ b/apps/shared/function_app.h @@ -30,7 +30,10 @@ public: uint32_t m_modelVersion; uint32_t m_rangeVersion; Poincare::Preferences::AngleUnit m_angleUnitVersion; - }; + }; + static FunctionApp * app() { + return static_cast(::app()); + } virtual ~FunctionApp() = default; virtual FunctionStore * functionStore() { return static_cast(snapshot())->functionStore(); } virtual InputViewController * inputViewController() = 0; diff --git a/apps/shared/function_go_to_parameter_controller.cpp b/apps/shared/function_go_to_parameter_controller.cpp index 73fbbee44..153bd3df7 100644 --- a/apps/shared/function_go_to_parameter_controller.cpp +++ b/apps/shared/function_go_to_parameter_controller.cpp @@ -22,7 +22,7 @@ double FunctionGoToParameterController::parameterAtIndex(int index) { bool FunctionGoToParameterController::setParameterAtIndex(int parameterIndex, double f) { assert(parameterIndex == 0); - FunctionApp * myApp = (FunctionApp *)app(); + FunctionApp * myApp = FunctionApp::app(); ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); float y = function->evaluateAtAbscissa(f, myApp->localContext()); m_cursor->moveTo(f, y); diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 4a272e247..5c1b876bd 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -111,8 +111,7 @@ double FunctionGraphController::defaultCursorAbscissa() { } FunctionStore * FunctionGraphController::functionStore() const { - FunctionApp * myApp = static_cast(app()); - return myApp->functionStore(); + return FunctionApp::app()->functionStore(); } void FunctionGraphController::initCursorParameters() { diff --git a/apps/shared/function_list_controller.cpp b/apps/shared/function_list_controller.cpp index c2e9dee28..e6dc2d9fb 100644 --- a/apps/shared/function_list_controller.cpp +++ b/apps/shared/function_list_controller.cpp @@ -249,13 +249,11 @@ TabViewController * FunctionListController::tabController() const { } FunctionStore * FunctionListController::modelStore() { - FunctionApp * myApp = static_cast(app()); - return myApp->functionStore(); + return FunctionApp::app()->functionStore(); } InputViewController * FunctionListController::inputController() { - FunctionApp * myApp = static_cast(app()); - return myApp->inputViewController(); + return FunctionApp::app()->inputViewController(); } KDCoordinate FunctionListController::maxFunctionNameWidth() { diff --git a/apps/shared/list_parameter_controller.cpp b/apps/shared/list_parameter_controller.cpp index 567fa053c..479d13741 100644 --- a/apps/shared/list_parameter_controller.cpp +++ b/apps/shared/list_parameter_controller.cpp @@ -112,8 +112,7 @@ ExpiringPointer ListParameterController::function() { } FunctionStore * ListParameterController::functionStore() { - FunctionApp * a = static_cast(app()); - return a->functionStore(); + return FunctionApp::app()->functionStore(); } diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index 559809812..b08914e53 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -66,7 +66,7 @@ bool SumGraphController::handleEvent(Ion::Events::Event event) { } bool SumGraphController::moveCursorHorizontallyToPosition(double x) { - FunctionApp * myApp = static_cast(app()); + FunctionApp * myApp = FunctionApp::app(); assert(!m_record.isNull()); ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); double y = function->evaluateAtAbscissa(x, myApp->localContext()); @@ -138,7 +138,7 @@ void SumGraphController::reloadBannerView() { double result; Poincare::Layout functionLayout; if (m_step == Step::Result) { - FunctionApp * myApp = static_cast(app()); + FunctionApp * myApp = FunctionApp::app(); assert(!m_record.isNull()); ExpiringPointer function = myApp->functionStore()->modelForRecord(m_record); result = function->sumBetweenBounds(m_startSum, m_endSum, myApp->localContext()); diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index 559faa97e..be80085bc 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -336,8 +336,7 @@ void ValuesController::updateNumberOfColumns() { } FunctionStore * ValuesController::functionStore() const { - FunctionApp * myApp = static_cast(app()); - return myApp->functionStore(); + return FunctionApp::app()->functionStore(); } } diff --git a/apps/shared/values_function_parameter_controller.cpp b/apps/shared/values_function_parameter_controller.cpp index 059c9a34e..4f68ad405 100644 --- a/apps/shared/values_function_parameter_controller.cpp +++ b/apps/shared/values_function_parameter_controller.cpp @@ -9,8 +9,7 @@ const char * ValuesFunctionParameterController::title() { } void ValuesFunctionParameterController::viewWillAppear() { - FunctionApp * myApp = static_cast(app()); - myApp->functionStore()->modelForRecord(m_record)->nameWithArgument(m_pageTitle, Function::k_maxNameWithArgumentSize, m_symbol); + FunctionApp::app()->functionStore()->modelForRecord(m_record)->nameWithArgument(m_pageTitle, Function::k_maxNameWithArgumentSize, m_symbol); } void ValuesFunctionParameterController::didBecomeFirstResponder() { From 96111332765b48531fee5a8d85810a3cfae73f76 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 11:24:42 +0200 Subject: [PATCH 077/111] [apps] Factor Shared::TextFieldDelegateApp::isAcceptableText --- apps/calculation/edit_expression_controller.cpp | 1 - apps/shared/text_field_delegate_app.cpp | 7 +++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index de82ba2d7..bcb0540bc 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -121,7 +121,6 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event /* The input text store in m_cacheBuffer might have beed correct the first * time but then be too long when replacing ans in another context */ if (!app()->isAcceptableText(m_cacheBuffer)) { - app()->displayWarning(I18n::Message::SyntaxError); return true; } m_calculationStore->push(m_cacheBuffer, app()->localContext()); diff --git a/apps/shared/text_field_delegate_app.cpp b/apps/shared/text_field_delegate_app.cpp index 95efd302f..8287cee34 100644 --- a/apps/shared/text_field_delegate_app.cpp +++ b/apps/shared/text_field_delegate_app.cpp @@ -25,7 +25,6 @@ bool TextFieldDelegateApp::textFieldShouldFinishEditing(TextField * textField, I bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { if (textField->isEditing() && textField->shouldFinishEditing(event)) { if (!isAcceptableText(textField->text())) { - displayWarning(I18n::Message::SyntaxError); return true; } } @@ -38,7 +37,11 @@ bool TextFieldDelegateApp::textFieldDidReceiveEvent(TextField * textField, Ion:: bool TextFieldDelegateApp::isAcceptableText(const char * text) { Expression exp = Expression::Parse(text); - return isAcceptableExpression(exp); + bool isAcceptable = isAcceptableExpression(exp); + if (!isAcceptable) { + displayWarning(I18n::Message::SyntaxError); + } + return isAcceptable; } bool TextFieldDelegateApp::hasUndefinedValue(const char * text, double & value) { From 28f713e9055b7052bd33524d57e934227b95ff2c Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 11:27:46 +0200 Subject: [PATCH 078/111] [apps/shared] Make App accessors const in delegates --- apps/shared/input_event_handler_delegate.h | 2 +- apps/shared/layout_field_delegate.h | 2 +- apps/shared/text_field_delegate.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/shared/input_event_handler_delegate.h b/apps/shared/input_event_handler_delegate.h index 1382921d9..902cbdee0 100644 --- a/apps/shared/input_event_handler_delegate.h +++ b/apps/shared/input_event_handler_delegate.h @@ -10,7 +10,7 @@ public: Toolbox * toolboxForInputEventHandler(InputEventHandler * textInput) override { return inputEventHandlerDelegateApp()->toolboxForInputEventHandler(textInput); } NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override { return inputEventHandlerDelegateApp()->variableBoxForInputEventHandler(textInput); } private: - InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() { + InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() const { return static_cast(::app()); } }; diff --git a/apps/shared/layout_field_delegate.h b/apps/shared/layout_field_delegate.h index 8caab47dc..755c8c335 100644 --- a/apps/shared/layout_field_delegate.h +++ b/apps/shared/layout_field_delegate.h @@ -13,7 +13,7 @@ public: bool layoutFieldDidAbortEditing(LayoutField * layoutField) override; void layoutFieldDidChangeSize(LayoutField * layoutField) override; private: - ExpressionFieldDelegateApp * expressionFieldDelegateApp() { + ExpressionFieldDelegateApp * expressionFieldDelegateApp() const { return static_cast(::app()); } }; diff --git a/apps/shared/text_field_delegate.h b/apps/shared/text_field_delegate.h index 3d12bca36..a434c59f2 100644 --- a/apps/shared/text_field_delegate.h +++ b/apps/shared/text_field_delegate.h @@ -10,7 +10,7 @@ public: bool textFieldShouldFinishEditing(TextField * textField, Ion::Events::Event event) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; protected: - TextFieldDelegateApp * textFieldDelegateApp() { + TextFieldDelegateApp * textFieldDelegateApp() const { return static_cast(::app()); } }; From 3e992a3560f9d76be49d7952659aeb58c9996b2e Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 18:14:33 +0200 Subject: [PATCH 079/111] [apps] Replace app() by textFieldDelegateApp() in TextFieldDelegates --- apps/calculation/edit_expression_controller.cpp | 9 +++++---- apps/graph/graph/calculation_graph_controller.cpp | 2 +- apps/graph/graph/graph_controller.cpp | 3 ++- apps/graph/graph/tangent_graph_controller.cpp | 13 ++++++++----- apps/graph/values/values_controller.cpp | 5 +++-- apps/probability/calculation_controller.cpp | 2 +- apps/sequence/graph/graph_controller.cpp | 7 ++++--- apps/sequence/list/list_parameter_controller.cpp | 2 +- .../settings/sub_menu/display_mode_controller.cpp | 2 +- apps/shared/function_graph_controller.cpp | 15 ++++++--------- apps/shared/values_controller.cpp | 3 +-- apps/solver/interval_controller.cpp | 2 +- apps/solver/list_controller.cpp | 2 +- 13 files changed, 35 insertions(+), 32 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index bcb0540bc..f46b16622 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -69,7 +69,7 @@ bool EditExpressionController::textFieldDidReceiveEvent(::TextField * textField, if (inputViewDidReceiveEvent(event, shouldDuplicateLastCalculation)) { return true; } - return app()->textFieldDidReceiveEvent(textField, event); + return textFieldDelegateApp()->textFieldDidReceiveEvent(textField, event); } bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text, Ion::Events::Event event) { @@ -120,10 +120,11 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event if (shouldDuplicateLastCalculation && m_cacheBuffer[0] != 0) { /* The input text store in m_cacheBuffer might have beed correct the first * time but then be too long when replacing ans in another context */ - if (!app()->isAcceptableText(m_cacheBuffer)) { + Shared::TextFieldDelegateApp * myApp = textFieldDelegateApp(); + if (!myApp->isAcceptableText(m_cacheBuffer)) { return true; } - m_calculationStore->push(m_cacheBuffer, app()->localContext()); + m_calculationStore->push(m_cacheBuffer, myApp->localContext()); m_historyController->reload(); ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); return true; @@ -147,7 +148,7 @@ bool EditExpressionController::inputViewDidFinishEditing(const char * text, Layo } else { layoutR.serializeParsedExpression(m_cacheBuffer, k_cacheBufferSize); } - m_calculationStore->push(m_cacheBuffer, app()->localContext()); + m_calculationStore->push(m_cacheBuffer, textFieldDelegateApp()->localContext()); m_historyController->reload(); ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); ((ContentView *)view())->expressionField()->setEditing(true, true); diff --git a/apps/graph/graph/calculation_graph_controller.cpp b/apps/graph/graph/calculation_graph_controller.cpp index bb9513eec..dafde5ae7 100644 --- a/apps/graph/graph/calculation_graph_controller.cpp +++ b/apps/graph/graph/calculation_graph_controller.cpp @@ -48,7 +48,7 @@ Expression::Coordinate2D CalculationGraphController::computeNewPointOfInteresetF double step = m_graphRange->xGridUnit()/10.0; step = direction < 0 ? -step : step; double max = direction > 0 ? m_graphRange->xMax() : m_graphRange->xMin(); - return computeNewPointOfInterest(start, step, max, app()->localContext()); + return computeNewPointOfInterest(start, step, max, textFieldDelegateApp()->localContext()); } CartesianFunctionStore * CalculationGraphController::functionStore() const { diff --git a/apps/graph/graph/graph_controller.cpp b/apps/graph/graph/graph_controller.cpp index 30171637f..7240e0ba7 100644 --- a/apps/graph/graph/graph_controller.cpp +++ b/apps/graph/graph/graph_controller.cpp @@ -43,9 +43,10 @@ void GraphController::setDisplayDerivativeInBanner(bool displayDerivative) { float GraphController::interestingXHalfRange() const { float characteristicRange = 0.0f; + Poincare::Context * context = textFieldDelegateApp()->localContext(); for (int i = 0; i < functionStore()->numberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - float fRange = f->expressionReduced(app()->localContext()).characteristicXRange(*(app()->localContext()), Poincare::Preferences::sharedPreferences()->angleUnit()); + float fRange = f->expressionReduced(context).characteristicXRange(*context, Poincare::Preferences::sharedPreferences()->angleUnit()); if (!std::isnan(fRange)) { characteristicRange = maxFloat(fRange, characteristicRange); } diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 4c7808c8b..bd066ea33 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -33,18 +33,19 @@ void TangentGraphController::viewWillAppear() { void TangentGraphController::didBecomeFirstResponder() { if (curveView()->isMainViewSelected()) { m_bannerView->abscissaValue()->setParentResponder(this); - m_bannerView->abscissaValue()->setDelegates(app(), this); + m_bannerView->abscissaValue()->setDelegates(textFieldDelegateApp(), this); app()->setFirstResponder(m_bannerView->abscissaValue()); } } bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { + Shared::TextFieldDelegateApp * myApp = textFieldDelegateApp(); double floatBody; - if (app()->hasUndefinedValue(text, floatBody)) { + if (myApp->hasUndefinedValue(text, floatBody)) { return false; } ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); - double y = function->evaluateAtAbscissa(floatBody, app()->localContext()); + double y = function->evaluateAtAbscissa(floatBody, myApp->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); reloadBannerView(); @@ -65,16 +66,18 @@ void TangentGraphController::reloadBannerView() { GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(m_cursor, m_record); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; + Poincare::Context * context = textFieldDelegateApp()->localContext(); + const char * legend = "a="; int legendLength = strlcpy(buffer, legend, bufferSize); ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); - double y = function->approximateDerivative(m_cursor->x(), app()->localContext()); + double y = function->approximateDerivative(m_cursor->x(), context); PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); m_bannerView->aView()->setText(buffer); legend = "b="; legendLength = strlcpy(buffer, legend, bufferSize); - y = -y*m_cursor->x()+function->evaluateAtAbscissa(m_cursor->x(), app()->localContext()); + y = -y*m_cursor->x()+function->evaluateAtAbscissa(m_cursor->x(), context); PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); m_bannerView->bView()->setText(buffer); m_bannerView->reload(); diff --git a/apps/graph/values/values_controller.cpp b/apps/graph/values/values_controller.cpp index 46e0e5123..6c2d00b09 100644 --- a/apps/graph/values/values_controller.cpp +++ b/apps/graph/values/values_controller.cpp @@ -147,10 +147,11 @@ double ValuesController::evaluationOfAbscissaAtColumn(double abscissa, int colum /* isDerivativeColumn uses expiring pointers, so "function" must be created * after the isDerivativeColumn call, else it will expire. */ Shared::ExpiringPointer function = functionStore()->modelForRecord(recordAtColumn(columnIndex)); + Poincare::Context * context = textFieldDelegateApp()->localContext(); if (isDerivative) { - return function->approximateDerivative(abscissa, app()->localContext()); + return function->approximateDerivative(abscissa, context); } - return function->evaluateAtAbscissa(abscissa, app()->localContext()); + return function->evaluateAtAbscissa(abscissa, context); } void ValuesController::updateNumberOfColumns() { diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index 91e939d2a..e63aeeaed 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -211,7 +211,7 @@ bool CalculationController::textFieldShouldFinishEditing(TextField * textField, bool CalculationController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (app()->hasUndefinedValue(text, floatBody)) { + if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { return false; } if (m_calculation->type() != Calculation::Type::FiniteIntegral && selectedColumn() == 2) { diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 68c0a1097..0aafbb3f8 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -61,12 +61,13 @@ float GraphController::interestingXHalfRange() const { } bool GraphController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { + Shared::TextFieldDelegateApp * myApp = textFieldDelegateApp(); double floatBody; - if (app()->hasUndefinedValue(text, floatBody)) { + if (myApp->hasUndefinedValue(text, floatBody)) { return false; } floatBody = std::fmax(0, std::round(floatBody)); - double y = yValue(selectedCurveIndex(), floatBody, app()->localContext()); + double y = yValue(selectedCurveIndex(), floatBody, myApp->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); reloadBannerView(); @@ -96,7 +97,7 @@ bool GraphController::moveCursorHorizontally(int direction) { return false; } Sequence * s = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(indexFunctionSelectedByCursor())); - double y = s->evaluateAtAbscissa(x, app()->localContext()); + double y = s->evaluateAtAbscissa(x, textFieldDelegateApp()->localContext()); m_cursor->moveTo(x, y); return true; } diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index d17d866f0..992ddb76e 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -72,7 +72,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c /* -1 to take into account a double recursive sequence, which has * SecondIndex = FirstIndex + 1 */ double floatBody; - if (app()->hasUndefinedValue(text, floatBody)) { + if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { return false; } int index = std::round(floatBody); diff --git a/apps/settings/sub_menu/display_mode_controller.cpp b/apps/settings/sub_menu/display_mode_controller.cpp index 8c22ca22a..29b94c25a 100644 --- a/apps/settings/sub_menu/display_mode_controller.cpp +++ b/apps/settings/sub_menu/display_mode_controller.cpp @@ -78,7 +78,7 @@ bool DisplayModeController::textFieldShouldFinishEditing(TextField * textField, bool DisplayModeController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { double floatBody; - if (app()->hasUndefinedValue(text, floatBody)) { + if (textFieldDelegateApp()->hasUndefinedValue(text, floatBody)) { return false; } if (floatBody < 1) { diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 5c1b876bd..a6312dd66 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -42,8 +42,7 @@ void FunctionGraphController::viewWillAppear() { functionGraphView()->setAreaHighlight(NAN,NAN); if (functionGraphView()->context() == nullptr) { - FunctionApp * myApp = static_cast(app()); - functionGraphView()->setContext(myApp->localContext()); + functionGraphView()->setContext(textFieldDelegateApp()->localContext()); } Preferences::AngleUnit newAngleUnitVersion = Preferences::sharedPreferences()->angleUnit(); if (*m_angleUnitVersion != newAngleUnitVersion) { @@ -74,7 +73,7 @@ void FunctionGraphController::reloadBannerView() { } InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange(InteractiveCurveViewRange * interactiveCurveViewRange) { - FunctionApp * myApp = static_cast(app()); + Poincare::Context * context = textFieldDelegateApp()->localContext(); float min = FLT_MAX; float max = -FLT_MAX; float xMin = interactiveCurveViewRange->xMin(); @@ -87,13 +86,12 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( } for (int i=0; inumberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - float y = 0.0f; float res = curveView()->resolution(); /* Scan x-range from the middle to the extrema in order to get balanced * y-range for even functions (y = 1/x). */ for (int j = -res/2; j <= res/2; j++) { float x = (xMin+xMax)/2.0+(xMax-xMin)*j/res; - y = f->evaluateAtAbscissa(x, myApp->localContext()); + float y = f->evaluateAtAbscissa(x, context); if (!std::isnan(y) && !std::isinf(y)) { min = min < y ? min : y; max = max > y ? max : y; @@ -116,12 +114,12 @@ FunctionStore * FunctionGraphController::functionStore() const { void FunctionGraphController::initCursorParameters() { double x = defaultCursorAbscissa(); - FunctionApp * myApp = static_cast(app()); + Poincare::Context * context = textFieldDelegateApp()->localContext(); int functionIndex = 0; double y = 0; do { ExpiringPointer firstFunction = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(functionIndex++)); - y = firstFunction->evaluateAtAbscissa(x, myApp->localContext()); + y = firstFunction->evaluateAtAbscissa(x, context); } while ((std::isnan(y) || std::isinf(y)) && functionIndex < functionStore()->numberOfActiveFunctions()); m_cursor->moveTo(x, y); functionIndex = (std::isnan(y) || std::isinf(y)) ? 0 : functionIndex - 1; @@ -133,8 +131,7 @@ void FunctionGraphController::initCursorParameters() { bool FunctionGraphController::moveCursorVertically(int direction) { int currentActiveFunctionIndex = indexFunctionSelectedByCursor(); - Poincare::Context * context = static_cast(app())->localContext(); - + Poincare::Context * context = textFieldDelegateApp()->localContext(); int nextActiveFunctionIndex = InteractiveCurveViewController::closestCurveIndexVertically(direction > 0, currentActiveFunctionIndex, context); if (nextActiveFunctionIndex < 0) { return false; diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index be80085bc..d2a1f7691 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -327,8 +327,7 @@ int ValuesController::maxNumberOfElements() const { double ValuesController::evaluationOfAbscissaAtColumn(double abscissa, int columnIndex) { ExpiringPointer function = functionStore()->modelForRecord(recordAtColumn(columnIndex)); - TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); - return function->evaluateAtAbscissa(abscissa, myApp->localContext()); + return function->evaluateAtAbscissa(abscissa, textFieldDelegateApp()->localContext()); } void ValuesController::updateNumberOfColumns() { diff --git a/apps/solver/interval_controller.cpp b/apps/solver/interval_controller.cpp index 19b1c5aed..8be37e5a8 100644 --- a/apps/solver/interval_controller.cpp +++ b/apps/solver/interval_controller.cpp @@ -103,7 +103,7 @@ bool IntervalController::textFieldDidFinishEditing(TextField * textField, const void IntervalController::buttonAction() { StackViewController * stack = stackController(); - m_equationStore->approximateSolve(app()->localContext()); + m_equationStore->approximateSolve(textFieldDelegateApp()->localContext()); stack->push(app()->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index c0ef1956d..3125c9188 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -175,7 +175,7 @@ void ListController::resolveEquations() { app()->displayWarning(I18n::Message::EnterEquation); return; } - EquationStore::Error e = m_equationStore->exactSolve(app()->localContext()); + EquationStore::Error e = m_equationStore->exactSolve(textFieldDelegateApp()->localContext()); switch (e) { case EquationStore::Error::EquationUndefined: app()->displayWarning(I18n::Message::UndefinedEquation); From 1a2a651f363e2b2e88a68172796163a813acb20b Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 10:47:24 +0200 Subject: [PATCH 080/111] [apps] Replace app() by expressionFieldDelegateApp() in Calculation::EditExpressionController --- apps/calculation/edit_expression_controller.cpp | 2 +- apps/shared/layout_field_delegate.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index f46b16622..25075501f 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -85,7 +85,7 @@ bool EditExpressionController::layoutFieldDidReceiveEvent(::LayoutField * layout if (inputViewDidReceiveEvent(event, shouldDuplicateLastCalculation)) { return true; } - return app()->layoutFieldDidReceiveEvent(layoutField, event); + return expressionFieldDelegateApp()->layoutFieldDidReceiveEvent(layoutField, event); } bool EditExpressionController::layoutFieldDidFinishEditing(::LayoutField * layoutField, Layout layoutR, Ion::Events::Event event) { diff --git a/apps/shared/layout_field_delegate.h b/apps/shared/layout_field_delegate.h index 755c8c335..fb30f6afd 100644 --- a/apps/shared/layout_field_delegate.h +++ b/apps/shared/layout_field_delegate.h @@ -12,7 +12,7 @@ public: bool layoutFieldDidFinishEditing(LayoutField * layoutField, Poincare::Layout layoutR, Ion::Events::Event event) override; bool layoutFieldDidAbortEditing(LayoutField * layoutField) override; void layoutFieldDidChangeSize(LayoutField * layoutField) override; -private: +protected: ExpressionFieldDelegateApp * expressionFieldDelegateApp() const { return static_cast(::app()); } From 44809f4b3f47381b84f427a9697568041f04d24d Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 18 Jul 2019 16:10:26 +0200 Subject: [PATCH 081/111] Substitute Escher app() by Container::activeApp() --- apps/calculation/app.h | 2 +- .../edit_expression_controller.cpp | 4 ++-- apps/calculation/history_controller.cpp | 14 ++++++------- apps/calculation/history_view_cell.cpp | 6 +++--- apps/code/app.h | 2 +- apps/code/console_controller.cpp | 4 ++-- apps/code/console_edit_cell.cpp | 2 +- apps/code/console_line_cell.cpp | 2 +- apps/code/editor_controller.cpp | 2 +- apps/code/editor_view.cpp | 2 +- apps/code/menu_controller.cpp | 18 ++++++++--------- apps/code/python_toolbox.cpp | 2 +- apps/code/script_name_cell.cpp | 2 +- apps/code/script_parameter_controller.cpp | 4 ++-- apps/code/variable_box_controller.cpp | 2 +- apps/exam_pop_up_controller.cpp | 7 +++---- apps/graph/app.h | 2 +- .../calculation_parameter_controller.cpp | 2 +- apps/graph/graph/tangent_graph_controller.cpp | 2 +- apps/graph/list/list_controller.cpp | 16 +++++++-------- .../list/text_field_function_title_cell.cpp | 4 ++-- .../derivative_parameter_controller.cpp | 2 +- apps/hardware_test/pop_up_controller.cpp | 6 +++--- apps/home/app.h | 2 +- apps/home/controller.cpp | 2 +- apps/math_toolbox.cpp | 2 +- apps/on_boarding/language_controller.cpp | 2 +- apps/on_boarding/logo_controller.cpp | 2 +- apps/on_boarding/pop_up_controller.cpp | 2 +- apps/probability/app.h | 2 +- apps/probability/calculation_controller.cpp | 4 ++-- .../calculation_type_controller.cpp | 6 +++--- apps/probability/law_controller.cpp | 2 +- apps/probability/parameters_controller.cpp | 2 +- apps/probability/responder_image_cell.cpp | 4 ++-- apps/regression/app.h | 2 +- apps/regression/calculation_controller.cpp | 4 ++-- .../regression/go_to_parameter_controller.cpp | 4 ++-- apps/regression/graph_options_controller.cpp | 3 +-- .../initialisation_parameter_controller.cpp | 2 +- apps/regression/regression_controller.cpp | 2 +- .../regression/store_parameter_controller.cpp | 2 +- apps/sequence/app.h | 2 +- apps/sequence/list/list_controller.cpp | 2 +- .../list/list_parameter_controller.cpp | 6 +++--- apps/sequence/list/sequence_toolbox.cpp | 2 +- .../list/type_parameter_controller.cpp | 4 ++-- .../values/interval_parameter_controller.cpp | 2 +- apps/settings/app.h | 4 ---- apps/settings/main_controller.cpp | 2 +- apps/settings/sub_menu/about_controller.cpp | 2 +- .../sub_menu/generic_sub_controller.cpp | 2 +- .../sub_menu/preferences_controller.cpp | 2 +- .../buffer_text_view_with_text_field.cpp | 2 +- .../editable_cell_table_view_controller.cpp | 2 +- apps/shared/float_parameter_controller.cpp | 2 +- apps/shared/function_app.h | 2 +- .../function_curve_parameter_controller.cpp | 2 +- apps/shared/function_graph_controller.cpp | 2 +- apps/shared/function_list_controller.cpp | 6 +++--- .../initialisation_parameter_controller.cpp | 2 +- apps/shared/input_event_handler_delegate.h | 2 +- .../interactive_curve_view_controller.cpp | 4 ++-- apps/shared/interval_parameter_controller.cpp | 4 ++-- apps/shared/language_controller.cpp | 2 +- apps/shared/layout_field_delegate.h | 2 +- apps/shared/list_parameter_controller.cpp | 2 +- apps/shared/message_controller.cpp | 2 +- ...ble_exact_approximate_expressions_cell.cpp | 2 +- apps/shared/store_controller.cpp | 14 ++++++------- apps/shared/store_parameter_controller.cpp | 2 +- apps/shared/sum_graph_controller.cpp | 8 ++++---- apps/shared/tab_table_controller.cpp | 2 +- apps/shared/text_field_delegate.h | 2 +- apps/shared/values_controller.cpp | 4 ++-- .../values_function_parameter_controller.cpp | 2 +- apps/shared/values_parameter_controller.cpp | 2 +- apps/solver/app.h | 2 +- apps/solver/equation_list_view.cpp | 2 +- .../equation_models_parameter_controller.cpp | 4 ++-- apps/solver/list_controller.cpp | 20 +++++++++---------- apps/solver/solutions_controller.cpp | 2 +- apps/statistics/calculation_controller.cpp | 2 +- .../histogram_parameter_controller.cpp | 10 +++++----- .../multiple_data_view_controller.cpp | 2 +- apps/variable_box_controller.cpp | 2 +- escher/include/escher/container.h | 4 ---- .../src/alternate_empty_view_controller.cpp | 2 +- escher/src/bank_view_controller.cpp | 4 ++-- escher/src/button_row_controller.cpp | 4 ++-- escher/src/editable_text_cell.cpp | 2 +- escher/src/even_odd_editable_text_cell.cpp | 2 +- escher/src/input_event_handler.cpp | 2 +- escher/src/input_view_controller.cpp | 2 +- .../message_table_cell_with_editable_text.cpp | 2 +- escher/src/modal_view_controller.cpp | 8 ++++---- escher/src/nested_menu_controller.cpp | 8 ++++---- escher/src/selectable_table_view.cpp | 6 +----- escher/src/stack_view_controller.cpp | 4 ++-- escher/src/tab_view_controller.cpp | 14 ++++++------- escher/src/warning_controller.cpp | 2 +- 101 files changed, 181 insertions(+), 197 deletions(-) diff --git a/apps/calculation/app.h b/apps/calculation/app.h index 0040fcd51..aee59a7ff 100644 --- a/apps/calculation/app.h +++ b/apps/calculation/app.h @@ -40,7 +40,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 25075501f..cb6ebdebf 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -61,7 +61,7 @@ void EditExpressionController::didBecomeFirstResponder() { int lastRow = m_calculationStore->numberOfCalculations() > 0 ? m_calculationStore->numberOfCalculations()-1 : 0; m_historyController->scrollToCell(0, lastRow); ((ContentView *)view())->expressionField()->setEditing(true, false); - app()->setFirstResponder(((ContentView *)view())->expressionField()); + Container::activeApp()->setFirstResponder(((ContentView *)view())->expressionField()); } bool EditExpressionController::textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) { @@ -133,7 +133,7 @@ bool EditExpressionController::inputViewDidReceiveEvent(Ion::Events::Event event if (m_calculationStore->numberOfCalculations() > 0) { m_cacheBuffer[0] = 0; ((ContentView *)view())->expressionField()->setEditing(false, false); - app()->setFirstResponder(m_historyController); + Container::activeApp()->setFirstResponder(m_historyController); } return true; } diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 8a60a1827..04b63ae46 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -24,7 +24,7 @@ void HistoryController::reload() { void HistoryController::didBecomeFirstResponder() { selectCellAtLocation(0, numberOfRows()-1); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } void HistoryController::willExitResponderChain(Responder * nextFirstResponder) { @@ -36,7 +36,7 @@ void HistoryController::willExitResponderChain(Responder * nextFirstResponder) { bool HistoryController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Down) { m_selectableTableView.deselectTable(); - app()->setFirstResponder(parentResponder()); + Container::activeApp()->setFirstResponder(parentResponder()); return true; } if (event == Ion::Events::Up) { @@ -48,7 +48,7 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { SubviewType subviewType = selectedSubviewType(); EditExpressionController * editController = (EditExpressionController *)parentResponder(); m_selectableTableView.deselectTable(); - app()->setFirstResponder(editController); + Container::activeApp()->setFirstResponder(editController); Calculation * calculation = m_calculationStore->calculationAtIndex(focusRow); if (subviewType == SubviewType::Input) { editController->insertTextBody(calculation->inputText()); @@ -72,7 +72,7 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { m_calculationStore->deleteCalculationAtIndex(focusRow); reload(); if (numberOfRows()== 0) { - app()->setFirstResponder(editController); + Container::activeApp()->setFirstResponder(editController); return true; } if (focusRow > 0) { @@ -92,13 +92,13 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { m_selectableTableView.deselectTable(); m_calculationStore->deleteAll(); reload(); - app()->setFirstResponder(parentResponder()); + Container::activeApp()->setFirstResponder(parentResponder()); return true; } if (event == Ion::Events::Back) { EditExpressionController * editController = (EditExpressionController *)parentResponder(); m_selectableTableView.deselectTable(); - app()->setFirstResponder(editController); + Container::activeApp()->setFirstResponder(editController); return true; } return false; @@ -120,7 +120,7 @@ void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int if (selectedCell == nullptr) { return; } - app()->setFirstResponder(selectedCell); + Container::activeApp()->setFirstResponder(selectedCell); } int HistoryController::numberOfRows() { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 3156a46a7..1e084c586 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -167,9 +167,9 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { void HistoryViewCell::didBecomeFirstResponder() { assert(m_dataSource); if (m_dataSource->selectedSubviewType() == HistoryViewCellDataSource::SubviewType::Input) { - app()->setFirstResponder(&m_inputView); + Container::activeApp()->setFirstResponder(&m_inputView); } else { - app()->setFirstResponder(&m_scrollableOutputView); + Container::activeApp()->setFirstResponder(&m_scrollableOutputView); } } @@ -181,7 +181,7 @@ bool HistoryViewCell::handleEvent(Ion::Events::Event event) { m_dataSource->setSelectedSubviewType(otherSubviewType, this); CalculationSelectableTableView * tableView = (CalculationSelectableTableView *)parentResponder(); tableView->scrollToSubviewOfTypeOfCellAtLocation(otherSubviewType, tableView->selectedColumn(), tableView->selectedRow()); - app()->setFirstResponder(this); + Container::activeApp()->setFirstResponder(this); return true; } return false; diff --git a/apps/code/app.h b/apps/code/app.h index 841c54542..f188a175e 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -85,7 +85,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index 9c2042020..8eb34d8fb 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -153,7 +153,7 @@ void ConsoleController::viewWillAppear() { } void ConsoleController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_editCell); + Container::activeApp()->setFirstResponder(&m_editCell); } bool ConsoleController::handleEvent(Ion::Events::Event event) { @@ -162,7 +162,7 @@ bool ConsoleController::handleEvent(Ion::Events::Event event) { const char * text = m_consoleStore.lineAtIndex(m_selectableTableView.selectedRow()).text(); m_editCell.setEditing(true); m_selectableTableView.selectCellAtLocation(0, m_consoleStore.numberOfLines()); - app()->setFirstResponder(&m_editCell); + Container::activeApp()->setFirstResponder(&m_editCell); return m_editCell.insertText(text); } } else if (event == Ion::Events::Clear) { diff --git a/apps/code/console_edit_cell.cpp b/apps/code/console_edit_cell.cpp index 9fc5ff585..8e1938aa8 100644 --- a/apps/code/console_edit_cell.cpp +++ b/apps/code/console_edit_cell.cpp @@ -35,7 +35,7 @@ void ConsoleEditCell::layoutSubviews() { } void ConsoleEditCell::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); } void ConsoleEditCell::setEditing(bool isEditing, bool reinitDraftBuffer) { diff --git a/apps/code/console_line_cell.cpp b/apps/code/console_line_cell.cpp index 5a696d57a..b0181b6a0 100644 --- a/apps/code/console_line_cell.cpp +++ b/apps/code/console_line_cell.cpp @@ -90,7 +90,7 @@ void ConsoleLineCell::layoutSubviews() { } void ConsoleLineCell::didBecomeFirstResponder() { - app()->setFirstResponder(&m_scrollableView); + Container::activeApp()->setFirstResponder(&m_scrollableView); } } diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index b07470d88..4c59d49c6 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -39,7 +39,7 @@ bool EditorController::handleEvent(Ion::Events::Event event) { } void EditorController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_editorView); + Container::activeApp()->setFirstResponder(&m_editorView); } void EditorController::viewWillAppear() { diff --git a/apps/code/editor_view.cpp b/apps/code/editor_view.cpp index cf883dc69..4138b5221 100644 --- a/apps/code/editor_view.cpp +++ b/apps/code/editor_view.cpp @@ -31,7 +31,7 @@ View * EditorView::subviewAtIndex(int index) { } void EditorView::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textArea); + Container::activeApp()->setFirstResponder(&m_textArea); } void EditorView::layoutSubviews() { diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index dabd1e7a8..25bcf67aa 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -61,14 +61,14 @@ void MenuController::didBecomeFirstResponder() { } if (footer()->selectedButton() == 0) { assert(m_selectableTableView.selectedRow() < 0); - app()->setFirstResponder(&m_consoleButton); + Container::activeApp()->setFirstResponder(&m_consoleButton); return; } if (m_selectableTableView.selectedRow() < 0) { m_selectableTableView.selectCellAtLocation(0,0); } assert(m_selectableTableView.selectedRow() < m_scriptStore->numberOfScripts() + 1); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); #if EPSILON_GETOPT if (consoleController()->locked()) { consoleController()->setAutoImport(true); @@ -92,7 +92,7 @@ bool MenuController::handleEvent(Ion::Events::Event event) { if (footer()->selectedButton() == 0) { footer()->setSelectedButton(-1); m_selectableTableView.selectCellAtLocation(0, numberOfRows()-1); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); return true; } } @@ -124,7 +124,7 @@ void MenuController::renameSelectedScript() { AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); m_selectableTableView.selectCellAtLocation(0, (m_selectableTableView.selectedRow())); ScriptNameCell * myCell = static_cast(m_selectableTableView.selectedCell()); - app()->setFirstResponder(myCell); + Container::activeApp()->setFirstResponder(myCell); myCell->setHighlighted(false); myCell->textField()->setEditing(true, false); myCell->textField()->setCursorLocation(myCell->textField()->text() + strlen(myCell->textField()->text())); @@ -337,16 +337,16 @@ bool MenuController::textFieldDidFinishEditing(TextField * textField, const char } m_selectableTableView.selectedCell()->setHighlighted(true); reloadConsole(); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } else if (error == Script::ErrorStatus::NameTaken) { - app()->displayWarning(I18n::Message::NameTaken); + Container::activeApp()->displayWarning(I18n::Message::NameTaken); } else if (error == Script::ErrorStatus::NonCompliantName) { - app()->displayWarning(I18n::Message::AllowedCharactersaz09, I18n::Message::NameCannotStartWithNumber); + Container::activeApp()->displayWarning(I18n::Message::AllowedCharactersaz09, I18n::Message::NameCannotStartWithNumber); } else { assert(error == Script::ErrorStatus::NotEnoughSpaceAvailable); - app()->displayWarning(I18n::Message::NameTooLong); + Container::activeApp()->displayWarning(I18n::Message::NameTooLong); } return false; } @@ -420,7 +420,7 @@ bool MenuController::privateTextFieldDidAbortEditing(TextField * textField, bool textField->setText(scriptName); if (menuControllerStaysInResponderChain) { m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; diff --git a/apps/code/python_toolbox.cpp b/apps/code/python_toolbox.cpp index a002b7f8a..6fa965ac4 100644 --- a/apps/code/python_toolbox.cpp +++ b/apps/code/python_toolbox.cpp @@ -370,7 +370,7 @@ bool PythonToolbox::selectLeaf(int selectedRow) { editedText = strippedEditedText; } sender()->handleEventWithText(editedText, true); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/apps/code/script_name_cell.cpp b/apps/code/script_name_cell.cpp index 8dbc6564b..26792e7f2 100644 --- a/apps/code/script_name_cell.cpp +++ b/apps/code/script_name_cell.cpp @@ -26,7 +26,7 @@ KDSize ScriptNameCell::minimalSizeForOptimalDisplay() const { } void ScriptNameCell::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); } void ScriptNameCell::layoutSubviews() { diff --git a/apps/code/script_parameter_controller.cpp b/apps/code/script_parameter_controller.cpp index 7dda64195..7a8e67b23 100644 --- a/apps/code/script_parameter_controller.cpp +++ b/apps/code/script_parameter_controller.cpp @@ -45,7 +45,7 @@ bool ScriptParameterController::handleEvent(Ion::Events::Event event) { m_script.toggleImportationStatus(); m_selectableTableView.reloadData(); m_menuController->reloadConsole(); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); return true; case 3: dismissScriptParameterController(); @@ -67,7 +67,7 @@ void ScriptParameterController::viewWillAppear() { void ScriptParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } HighlightCell * ScriptParameterController::reusableCell(int index) { diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index b8345ec01..88f981942 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -100,7 +100,7 @@ bool VariableBoxController::selectLeaf(int rowIndex) { if (selectedScriptNode.type() == ScriptNode::Type::Function) { insertTextInCaller(ScriptNodeCell::k_parenthesesWithEmpty); } - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/apps/exam_pop_up_controller.cpp b/apps/exam_pop_up_controller.cpp index 94d06c41c..4b3a38f01 100644 --- a/apps/exam_pop_up_controller.cpp +++ b/apps/exam_pop_up_controller.cpp @@ -47,8 +47,7 @@ bool ExamPopUpController::handleEvent(Ion::Events::Event event) { ExamPopUpController::ContentView::ContentView(Responder * parentResponder) : m_cancelButton(parentResponder, I18n::Message::Cancel, Invocation([](void * context, void * sender) { - AppsContainer * container = AppsContainer::sharedAppsContainer(); - container->activeApp()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; }, parentResponder), KDFont::SmallFont), m_okButton(parentResponder, I18n::Message::Ok, Invocation([](void * context, void * sender) { @@ -64,7 +63,7 @@ ExamPopUpController::ContentView::ContentView(Responder * parentResponder) : Ion::LED::setColor(KDColorBlack); } container->refreshPreferences(); - container->activeApp()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; }, parentResponder), KDFont::SmallFont), m_warningTextView(KDFont::SmallFont, I18n::Message::Warning, 0.5, 0.5, KDColorWhite, KDColorBlack), @@ -81,7 +80,7 @@ void ExamPopUpController::ContentView::drawRect(KDContext * ctx, KDRect rect) co void ExamPopUpController::ContentView::setSelectedButton(int selectedButton) { m_cancelButton.setHighlighted(selectedButton == 0); m_okButton.setHighlighted(selectedButton == 1); - app()->setFirstResponder(selectedButton == 0 ? &m_cancelButton : &m_okButton); + Container::activeApp()->setFirstResponder(selectedButton == 0 ? &m_cancelButton : &m_okButton); } int ExamPopUpController::ContentView::selectedButton() { diff --git a/apps/graph/app.h b/apps/graph/app.h index 362dfe858..d3f7a5314 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -53,7 +53,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/graph/graph/calculation_parameter_controller.cpp b/apps/graph/graph/calculation_parameter_controller.cpp index f7df007b4..3f96e23b4 100644 --- a/apps/graph/graph/calculation_parameter_controller.cpp +++ b/apps/graph/graph/calculation_parameter_controller.cpp @@ -33,7 +33,7 @@ View * CalculationParameterController::view() { void CalculationParameterController::didBecomeFirstResponder() { m_selectableTableView.selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool CalculationParameterController::handleEvent(Ion::Events::Event event) { diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index bd066ea33..33e9589d1 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -34,7 +34,7 @@ void TangentGraphController::didBecomeFirstResponder() { if (curveView()->isMainViewSelected()) { m_bannerView->abscissaValue()->setParentResponder(this); m_bannerView->abscissaValue()->setDelegates(textFieldDelegateApp(), this); - app()->setFirstResponder(m_bannerView->abscissaValue()); + Container::activeApp()->setFirstResponder(m_bannerView->abscissaValue()); } } diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 5d7a26a02..ed17fd5d5 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -41,7 +41,7 @@ void ListController::renameSelectedFunction() { AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::AlphaLock); TextFieldFunctionTitleCell * selectedTitleCell = (TextFieldFunctionTitleCell *)(selectableTableView()->selectedCell()); selectedTitleCell->setHorizontalAlignment(1.0f); - app()->setFirstResponder(selectedTitleCell); + Container::activeApp()->setFirstResponder(selectedTitleCell); selectedTitleCell->setEditing(true); } @@ -87,27 +87,27 @@ bool ListController::textFieldDidFinishEditing(TextField * textField, const char } m_selectableTableView.selectedCell()->setHighlighted(true); m_selectableTableView.reloadData(); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); if (selectTab) { m_selectableTableView.parentResponder()->handleEvent(event); } AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } else if (error == Ion::Storage::Record::ErrorStatus::NameTaken) { - app()->displayWarning(I18n::Message::NameTaken); + Container::activeApp()->displayWarning(I18n::Message::NameTaken); } else if (error == Ion::Storage::Record::ErrorStatus::NonCompliantName) { assert(nameError != Function::NameNotCompliantError::None); if (nameError == Function::NameNotCompliantError::CharacterNotAllowed) { - app()->displayWarning(I18n::Message::AllowedCharactersAZaz09); + Container::activeApp()->displayWarning(I18n::Message::AllowedCharactersAZaz09); } else if (nameError == Function::NameNotCompliantError::NameCannotStartWithNumber) { - app()->displayWarning(I18n::Message::NameCannotStartWithNumber); + Container::activeApp()->displayWarning(I18n::Message::NameCannotStartWithNumber); } else { assert(nameError == Function::NameNotCompliantError::ReservedName); - app()->displayWarning(I18n::Message::ReservedName); + Container::activeApp()->displayWarning(I18n::Message::ReservedName); } } else { assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable); - app()->displayWarning(I18n::Message::NameTooLong); + Container::activeApp()->displayWarning(I18n::Message::NameTooLong); } textField->setEditing(true, false); return false; @@ -121,7 +121,7 @@ bool ListController::textFieldDidAbortEditing(TextField * textField) { ExpiringPointer function = modelStore()->modelForRecord(modelStore()->recordAtIndex(selectedRow())); setFunctionNameInTextField(function, textField); m_selectableTableView.selectedCell()->setHighlighted(true); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); AppsContainer::sharedAppsContainer()->setShiftAlphaStatus(Ion::Events::ShiftAlphaStatus::Default); return true; } diff --git a/apps/graph/list/text_field_function_title_cell.cpp b/apps/graph/list/text_field_function_title_cell.cpp index 56057d888..16ef037c3 100644 --- a/apps/graph/list/text_field_function_title_cell.cpp +++ b/apps/graph/list/text_field_function_title_cell.cpp @@ -24,7 +24,7 @@ Responder * TextFieldFunctionTitleCell::responder() { } void TextFieldFunctionTitleCell::setEditing(bool editing) { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); const char * previousText = m_textField.text(); m_textField.setEditing(true, false); m_textField.setText(previousText); @@ -67,7 +67,7 @@ void TextFieldFunctionTitleCell::layoutSubviews() { void TextFieldFunctionTitleCell::didBecomeFirstResponder() { if (isEditing()) { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); } } diff --git a/apps/graph/values/derivative_parameter_controller.cpp b/apps/graph/values/derivative_parameter_controller.cpp index 4a411bf58..18f6188fd 100644 --- a/apps/graph/values/derivative_parameter_controller.cpp +++ b/apps/graph/values/derivative_parameter_controller.cpp @@ -31,7 +31,7 @@ View * DerivativeParameterController::view() { void DerivativeParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool DerivativeParameterController::handleEvent(Ion::Events::Event event) { diff --git a/apps/hardware_test/pop_up_controller.cpp b/apps/hardware_test/pop_up_controller.cpp index 954bf5c13..24a0592b5 100644 --- a/apps/hardware_test/pop_up_controller.cpp +++ b/apps/hardware_test/pop_up_controller.cpp @@ -35,7 +35,7 @@ bool PopUpController::handleEvent(Ion::Events::Event event) { PopUpController::ContentView::ContentView(Responder * parentResponder) : Responder(parentResponder), m_cancelButton(this, I18n::Message::Cancel, Invocation([](void * context, void * sender) { - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; }, this), KDFont::SmallFont), m_okButton(this, I18n::Message::Ok, Invocation([](void * context, void * sender) { @@ -61,9 +61,9 @@ void PopUpController::ContentView::setSelectedButton(int selectedButton) { m_cancelButton.setHighlighted(selectedButton == 0); m_okButton.setHighlighted(selectedButton == 1); if (selectedButton == 0) { - app()->setFirstResponder(&m_cancelButton); + Container::activeApp()->setFirstResponder(&m_cancelButton); } else { - app()->setFirstResponder(&m_okButton); + Container::activeApp()->setFirstResponder(&m_okButton); } } diff --git a/apps/home/app.h b/apps/home/app.h index d483c89e3..22ab0e4fd 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -27,7 +27,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 238aa0b35..185a842fb 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -81,7 +81,7 @@ void Controller::didBecomeFirstResponder() { if (selectionDataSource()->selectedRow() == -1) { selectionDataSource()->selectCellAtLocation(0, 0); } - app()->setFirstResponder(m_view.selectableTableView()); + Container::activeApp()->setFirstResponder(m_view.selectableTableView()); } void Controller::viewWillAppear() { diff --git a/apps/math_toolbox.cpp b/apps/math_toolbox.cpp index 7d449d3c2..5d49250d4 100644 --- a/apps/math_toolbox.cpp +++ b/apps/math_toolbox.cpp @@ -120,7 +120,7 @@ bool MathToolbox::selectLeaf(int selectedRow) { text = textToInsert; } sender()->handleEventWithText(text); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/apps/on_boarding/language_controller.cpp b/apps/on_boarding/language_controller.cpp index 6e76bae4b..6d2753b9e 100644 --- a/apps/on_boarding/language_controller.cpp +++ b/apps/on_boarding/language_controller.cpp @@ -13,7 +13,7 @@ bool LanguageController::handleEvent(Ion::Events::Event event) { if (Shared::LanguageController::handleEvent(event)) { AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); #ifdef EPSILON_BOOT_PROMPT - app()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); + Container::activeApp()->displayModalViewController(appsContainer->promptController(), 0.5f, 0.5f); #else appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0)); #endif diff --git a/apps/on_boarding/logo_controller.cpp b/apps/on_boarding/logo_controller.cpp index 3068da16c..c63ebadca 100644 --- a/apps/on_boarding/logo_controller.cpp +++ b/apps/on_boarding/logo_controller.cpp @@ -14,7 +14,7 @@ View * LogoController::view() { } bool LogoController::fire() { - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/apps/on_boarding/pop_up_controller.cpp b/apps/on_boarding/pop_up_controller.cpp index af60e384d..61cf77906 100644 --- a/apps/on_boarding/pop_up_controller.cpp +++ b/apps/on_boarding/pop_up_controller.cpp @@ -52,7 +52,7 @@ PopUpController::PopUpController(I18n::Message * messages, KDColor * colors, uin bool PopUpController::handleEvent(Ion::Events::Event event) { if (event != Ion::Events::Back && event != Ion::Events::OnOff && event != Ion::Events::USBPlug && event != Ion::Events::USBEnumeration) { - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); if (appsContainer->activeApp()->snapshot() == appsContainer->onBoardingAppSnapshot()) { bool switched = appsContainer->switchTo(appsContainer->appSnapshotAtIndex(0)); diff --git a/apps/probability/app.h b/apps/probability/app.h index a8cdd606d..59841f1f1 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -64,7 +64,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index e63aeeaed..dd86480c1 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -86,7 +86,7 @@ void CalculationController::didEnterResponderChain(Responder * previousResponder } void CalculationController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } View * CalculationController::view() { @@ -192,7 +192,7 @@ bool CalculationController::textFieldDidHandleEvent(::TextField * textField, boo /* We do not reload the responder because the first responder might be the * toolbox (or the variable box) and reloading the responder would corrupt * the first responder. */ - bool shouldUpdateFirstResponder = app()->firstResponder() == textField; + bool shouldUpdateFirstResponder = Container::activeApp()->firstResponder() == textField; m_selectableTableView.reloadData(shouldUpdateFirstResponder); // The textField frame might have increased which forces to reload the textField scroll textField->scrollToCursor(); diff --git a/apps/probability/calculation_type_controller.cpp b/apps/probability/calculation_type_controller.cpp index aef5c6527..b793277f4 100644 --- a/apps/probability/calculation_type_controller.cpp +++ b/apps/probability/calculation_type_controller.cpp @@ -39,21 +39,21 @@ void CalculationTypeController::viewDidDisappear() { } void CalculationTypeController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool CalculationTypeController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE) { m_calculationController->setCalculationAccordingToIndex(selectedRow()); m_calculationController->reload(); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } if (event == Ion::Events::Back || event == Ion::Events::Right) { if (event == Ion::Events::Right) { m_calculationController->selectCellAtLocation(1,0); } - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } return false; diff --git a/apps/probability/law_controller.cpp b/apps/probability/law_controller.cpp index 60e5eb596..14ae76ee4 100644 --- a/apps/probability/law_controller.cpp +++ b/apps/probability/law_controller.cpp @@ -79,7 +79,7 @@ void Probability::LawController::didBecomeFirstResponder() { } else { selectCellAtLocation(selectedColumn(), selectedRow()); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool Probability::LawController::handleEvent(Ion::Events::Event event) { diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index d6bb367d2..eaeddf52a 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -144,7 +144,7 @@ double ParametersController::parameterAtIndex(int index) { bool ParametersController::setParameterAtIndex(int parameterIndex, double f) { if (!m_law->authorizedValueAtIndex(f, parameterIndex)) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } m_law->setParameterAtIndex(f, parameterIndex); diff --git a/apps/probability/responder_image_cell.cpp b/apps/probability/responder_image_cell.cpp index a69274ee6..947bde386 100644 --- a/apps/probability/responder_image_cell.cpp +++ b/apps/probability/responder_image_cell.cpp @@ -21,8 +21,8 @@ KDSize ResponderImageCell::minimalSizeForOptimalDisplay() const { bool ResponderImageCell::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Down) { - KDPoint topLeftAngle = app()->modalView()->pointFromPointInView(this, KDPoint(k_outline, k_outline)); - app()->displayModalViewController(&m_calculationTypeController, 0.0f, 0.0f, topLeftAngle.y(), topLeftAngle.x()); + KDPoint topLeftAngle = Container::activeApp()->modalView()->pointFromPointInView(this, KDPoint(k_outline, k_outline)); + Container::activeApp()->displayModalViewController(&m_calculationTypeController, 0.0f, 0.0f, topLeftAngle.y(), topLeftAngle.x()); return true; } return false; diff --git a/apps/regression/app.h b/apps/regression/app.h index 06f443195..ebac8db7a 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -58,7 +58,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index cb1e4ea40..be96868a0 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -50,7 +50,7 @@ const char * CalculationController::title() { bool CalculationController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { selectableTableView()->deselectTable(); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } return false; @@ -78,7 +78,7 @@ void CalculationController::tableViewDidChangeSelection(SelectableTableView * t, if (t->selectedRow() == 0 && t->selectedColumn() == 0) { if (previousSelectedCellX == 0 && previousSelectedCellY == 1) { selectableTableView()->deselectTable(); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); } else { t->selectCellAtLocation(0, 1); } diff --git a/apps/regression/go_to_parameter_controller.cpp b/apps/regression/go_to_parameter_controller.cpp index 5074050ad..4d6c1c602 100644 --- a/apps/regression/go_to_parameter_controller.cpp +++ b/apps/regression/go_to_parameter_controller.cpp @@ -57,7 +57,7 @@ bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) } } // Value not reached - app()->displayWarning(I18n::Message::ValueNotReachedByRegression); + Container::activeApp()->displayWarning(I18n::Message::ValueNotReachedByRegression); return false; } m_graphController->selectRegressionCurve(); @@ -68,7 +68,7 @@ bool GoToParameterController::setParameterAtIndex(int parameterIndex, double f) /* We here compute y2 = a*((y1-b)/a)+b, which does not always give y1, * because of computation precision. y2 migth thus be invalid. */ if (std::isnan(yFromX) || std::isinf(yFromX)) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } m_cursor->moveTo(unknown, yFromX); diff --git a/apps/regression/graph_options_controller.cpp b/apps/regression/graph_options_controller.cpp index 642f43ef9..b61e489a0 100644 --- a/apps/regression/graph_options_controller.cpp +++ b/apps/regression/graph_options_controller.cpp @@ -2,7 +2,6 @@ #include "app.h" #include "graph_controller.h" #include "regression_controller.h" -#include #include using namespace Shared; @@ -32,7 +31,7 @@ void GraphOptionsController::didBecomeFirstResponder() { if (selectedRow() < 0) { selectCellAtLocation(0, 0); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } void GraphOptionsController::viewWillAppear() { diff --git a/apps/regression/initialisation_parameter_controller.cpp b/apps/regression/initialisation_parameter_controller.cpp index ac811b1bb..76600ce88 100644 --- a/apps/regression/initialisation_parameter_controller.cpp +++ b/apps/regression/initialisation_parameter_controller.cpp @@ -22,7 +22,7 @@ View * InitialisationParameterController::view() { void InitialisationParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool InitialisationParameterController::handleEvent(Ion::Events::Event event) { diff --git a/apps/regression/regression_controller.cpp b/apps/regression/regression_controller.cpp index 0376701c9..9cc70181f 100644 --- a/apps/regression/regression_controller.cpp +++ b/apps/regression/regression_controller.cpp @@ -30,7 +30,7 @@ const char * RegressionController::title() { void RegressionController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool RegressionController::handleEvent(Ion::Events::Event event) { diff --git a/apps/regression/store_parameter_controller.cpp b/apps/regression/store_parameter_controller.cpp index a82408cd5..07d5095a9 100644 --- a/apps/regression/store_parameter_controller.cpp +++ b/apps/regression/store_parameter_controller.cpp @@ -37,7 +37,7 @@ void StoreParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); } m_lastSelectionIsRegression = false; - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } HighlightCell * StoreParameterController::reusableCell(int index, int type) { diff --git a/apps/sequence/app.h b/apps/sequence/app.h index 1201105fe..2208cc095 100644 --- a/apps/sequence/app.h +++ b/apps/sequence/app.h @@ -59,7 +59,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index dad72cdd7..4b600141d 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -258,7 +258,7 @@ int ListController::sequenceDefinitionForRow(int j) { } void ListController::addEmptyModel() { - app()->displayModalViewController(&m_typeStackController, 0.f, 0.f, Metric::TabHeight+Metric::ModalTopMargin, Metric::CommonRightMargin, Metric::ModalBottomMargin, Metric::CommonLeftMargin); + Container::activeApp()->displayModalViewController(&m_typeStackController, 0.f, 0.f, Metric::TabHeight+Metric::ModalTopMargin, Metric::CommonRightMargin, Metric::ModalBottomMargin, Metric::CommonLeftMargin); } void ListController::editExpression(Ion::Events::Event event) { diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 992ddb76e..01958722a 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -77,7 +77,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c } int index = std::round(floatBody); if (index < 0 || floatBody >= maxFirstIndex) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } sequence()->setInitialRank(index); @@ -104,7 +104,7 @@ void ListParameterController::tableViewDidChangeSelection(SelectableTableView * if (myCell) { myCell->setEditing(false); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } #if FUNCTION_COLOR_CHOICE if (t->selectedRow() == 2) { @@ -112,7 +112,7 @@ void ListParameterController::tableViewDidChangeSelection(SelectableTableView * if (t->selectedRow() == 1) { #endif MessageTableCellWithEditableText * myNewCell = (MessageTableCellWithEditableText *)t->selectedCell(); - app()->setFirstResponder(myNewCell); + Container::activeApp()->setFirstResponder(myNewCell); } } diff --git a/apps/sequence/list/sequence_toolbox.cpp b/apps/sequence/list/sequence_toolbox.cpp index e6281baae..dc1db2667 100644 --- a/apps/sequence/list/sequence_toolbox.cpp +++ b/apps/sequence/list/sequence_toolbox.cpp @@ -99,7 +99,7 @@ bool SequenceToolbox::selectAddedCell(int selectedRow){ char buffer[bufferSize]; m_addedCellLayout[selectedRow].serializeParsedExpression(buffer, bufferSize); sender()->handleEventWithText(buffer); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/apps/sequence/list/type_parameter_controller.cpp b/apps/sequence/list/type_parameter_controller.cpp index de2c8d35a..637a79055 100644 --- a/apps/sequence/list/type_parameter_controller.cpp +++ b/apps/sequence/list/type_parameter_controller.cpp @@ -49,7 +49,7 @@ void TypeParameterController::viewDidDisappear() { void TypeParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool TypeParameterController::handleEvent(Ion::Events::Event event) { @@ -81,7 +81,7 @@ bool TypeParameterController::handleEvent(Ion::Events::Event event) { Ion::Storage::Record record = sequenceStore()->recordAtIndex(sequenceStore()->numberOfModels()-1); Sequence * newSequence = sequenceStore()->modelForRecord(record); newSequence->setType((Sequence::Type)selectedRow()); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); m_listController->editExpression(0, Ion::Events::OK); return true; } diff --git a/apps/sequence/values/interval_parameter_controller.cpp b/apps/sequence/values/interval_parameter_controller.cpp index eb337efc6..e5925ac82 100644 --- a/apps/sequence/values/interval_parameter_controller.cpp +++ b/apps/sequence/values/interval_parameter_controller.cpp @@ -22,7 +22,7 @@ void IntervalParameterController::willDisplayCellForIndex(HighlightCell * cell, bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double f) { if (f < 0) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } double parameter = std::round(f); diff --git a/apps/settings/app.h b/apps/settings/app.h index 3189364d4..3f4c064d0 100644 --- a/apps/settings/app.h +++ b/apps/settings/app.h @@ -25,10 +25,6 @@ private: StackViewController m_stackViewController; }; -inline App * app() { - return static_cast(::app()); -} - } #endif diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index df748f77e..fd664d74d 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -65,7 +65,7 @@ void MainController::didBecomeFirstResponder() { if (selectedRow() < 0) { selectCellAtLocation(0, 0); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool MainController::handleEvent(Ion::Events::Event event) { diff --git a/apps/settings/sub_menu/about_controller.cpp b/apps/settings/sub_menu/about_controller.cpp index 1596f6e44..12f28f996 100644 --- a/apps/settings/sub_menu/about_controller.cpp +++ b/apps/settings/sub_menu/about_controller.cpp @@ -18,7 +18,7 @@ bool AboutController::handleEvent(Ion::Events::Event event) { /* We hide here the activation hardware test app: in the menu "about", by * clicking on '6' on the last row. */ if ((event == Ion::Events::Six || event == Ion::Events::LowerT || event == Ion::Events::UpperT) && m_messageTreeModel->label() == I18n::Message::About && selectedRow() == numberOfRows()-1) { - app()->displayModalViewController(&m_hardwareTestPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin); + Container::activeApp()->displayModalViewController(&m_hardwareTestPopUpController, 0.f, 0.f, Metric::ExamPopUpTopMargin, Metric::PopUpRightMargin, Metric::ExamPopUpBottomMargin, Metric::PopUpLeftMargin); return true; } if (event == Ion::Events::OK || event == Ion::Events::EXE) { diff --git a/apps/settings/sub_menu/generic_sub_controller.cpp b/apps/settings/sub_menu/generic_sub_controller.cpp index 80ff32d8b..f69895893 100644 --- a/apps/settings/sub_menu/generic_sub_controller.cpp +++ b/apps/settings/sub_menu/generic_sub_controller.cpp @@ -28,7 +28,7 @@ View * GenericSubController::view() { void GenericSubController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool GenericSubController::handleEvent(Ion::Events::Event event) { diff --git a/apps/settings/sub_menu/preferences_controller.cpp b/apps/settings/sub_menu/preferences_controller.cpp index 45b684776..8f334dd6f 100644 --- a/apps/settings/sub_menu/preferences_controller.cpp +++ b/apps/settings/sub_menu/preferences_controller.cpp @@ -22,7 +22,7 @@ PreferencesController::PreferencesController(Responder * parentResponder) : void PreferencesController::didBecomeFirstResponder() { selectCellAtLocation(0, valueIndexForPreference(m_messageTreeModel->label())); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool PreferencesController::handleEvent(Ion::Events::Event event) { diff --git a/apps/shared/buffer_text_view_with_text_field.cpp b/apps/shared/buffer_text_view_with_text_field.cpp index 8d3bfb189..ca71591a1 100644 --- a/apps/shared/buffer_text_view_with_text_field.cpp +++ b/apps/shared/buffer_text_view_with_text_field.cpp @@ -40,7 +40,7 @@ void BufferTextViewWithTextField::drawRect(KDContext * ctx, KDRect rect) const { } void BufferTextViewWithTextField::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); m_textField.setEditing(true, false); markRectAsDirty(bounds()); } diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index 2e3ba723d..4e1ef615f 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -27,7 +27,7 @@ bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * text return false; } if (!setDataAtLocation(floatBody, selectedColumn(), selectedRow())) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } /* At this point, a new cell is selected depending on the event, before the diff --git a/apps/shared/float_parameter_controller.cpp b/apps/shared/float_parameter_controller.cpp index 540a5cece..58e273465 100644 --- a/apps/shared/float_parameter_controller.cpp +++ b/apps/shared/float_parameter_controller.cpp @@ -27,7 +27,7 @@ void FloatParameterController::didBecomeFirstResponder() { selColumn = selColumn >= numberOfColumns() ? numberOfColumns() - 1 : selColumn; selectCellAtLocation(selColumn, selRow); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } void FloatParameterController::viewWillAppear() { diff --git a/apps/shared/function_app.h b/apps/shared/function_app.h index 932ed30dd..797e41647 100644 --- a/apps/shared/function_app.h +++ b/apps/shared/function_app.h @@ -32,7 +32,7 @@ public: Poincare::Preferences::AngleUnit m_angleUnitVersion; }; static FunctionApp * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } virtual ~FunctionApp() = default; virtual FunctionStore * functionStore() { return static_cast(snapshot())->functionStore(); } diff --git a/apps/shared/function_curve_parameter_controller.cpp b/apps/shared/function_curve_parameter_controller.cpp index b401eb5de..d0a035e91 100644 --- a/apps/shared/function_curve_parameter_controller.cpp +++ b/apps/shared/function_curve_parameter_controller.cpp @@ -19,7 +19,7 @@ void FunctionCurveParameterController::didBecomeFirstResponder() { if (selectedRow() < 0) { selectCellAtLocation(0, 0); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool FunctionCurveParameterController::handleGotoSelection() { diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index a6312dd66..0b1c19a8b 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -31,7 +31,7 @@ void FunctionGraphController::didBecomeFirstResponder() { if (curveView()->isMainViewSelected()) { bannerView()->abscissaValue()->setParentResponder(this); bannerView()->abscissaValue()->setDelegates(textFieldDelegateApp(), this); - app()->setFirstResponder(bannerView()->abscissaValue()); + Container::activeApp()->setFirstResponder(bannerView()->abscissaValue()); } else { InteractiveCurveViewController::didBecomeFirstResponder(); } diff --git a/apps/shared/function_list_controller.cpp b/apps/shared/function_list_controller.cpp index e6dc2d9fb..1913a216e 100644 --- a/apps/shared/function_list_controller.cpp +++ b/apps/shared/function_list_controller.cpp @@ -154,7 +154,7 @@ void FunctionListController::didBecomeFirstResponder() { selectCellAtLocation(selectedColumn(), numberOfRows()-1); } footer()->setSelectedButton(-1); - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); } bool FunctionListController::handleEvent(Ion::Events::Event event) { @@ -162,12 +162,12 @@ bool FunctionListController::handleEvent(Ion::Events::Event event) { if (selectedRow() == -1) { footer()->setSelectedButton(-1); selectableTableView()->selectCellAtLocation(1, numberOfRows()-1); - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); return true; } selectableTableView()->deselectTable(); assert(selectedRow() == -1); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } if (event == Ion::Events::Down) { diff --git a/apps/shared/initialisation_parameter_controller.cpp b/apps/shared/initialisation_parameter_controller.cpp index 9c7cbe4fe..6e8fa00ce 100644 --- a/apps/shared/initialisation_parameter_controller.cpp +++ b/apps/shared/initialisation_parameter_controller.cpp @@ -29,7 +29,7 @@ if (event == Ion::Events::OK || event == Ion::Events::EXE) { void InitialisationParameterController::didBecomeFirstResponder() { m_selectableTableView.selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } int InitialisationParameterController::numberOfRows() { diff --git a/apps/shared/input_event_handler_delegate.h b/apps/shared/input_event_handler_delegate.h index 902cbdee0..07dbdaa2d 100644 --- a/apps/shared/input_event_handler_delegate.h +++ b/apps/shared/input_event_handler_delegate.h @@ -11,7 +11,7 @@ public: NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override { return inputEventHandlerDelegateApp()->variableBoxForInputEventHandler(textInput); } private: InputEventHandlerDelegateApp * inputEventHandlerDelegateApp() const { - return static_cast(::app()); + return static_cast(Container::activeApp()); } }; diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index c7ba92d93..74ea2fd6f 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -78,14 +78,14 @@ bool InteractiveCurveViewController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Down) { header()->setSelectedButton(-1); curveView()->selectMainView(true); - app()->setFirstResponder(this); + Container::activeApp()->setFirstResponder(this); reloadBannerView(); curveView()->reload(); return true; } if (event == Ion::Events::Up) { header()->setSelectedButton(-1); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } return false; diff --git a/apps/shared/interval_parameter_controller.cpp b/apps/shared/interval_parameter_controller.cpp index c53922fc2..019afd3d0 100644 --- a/apps/shared/interval_parameter_controller.cpp +++ b/apps/shared/interval_parameter_controller.cpp @@ -44,14 +44,14 @@ double IntervalParameterController::parameterAtIndex(int index) { bool IntervalParameterController::setParameterAtIndex(int parameterIndex, double f) { if (f <= 0.0f && parameterIndex == 2) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } double start = parameterIndex == 0 ? f : m_interval->start(); double end = parameterIndex == 1 ? f : m_interval->end(); if (start > end) { if (parameterIndex == 1) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } double g = f+1.0; diff --git a/apps/shared/language_controller.cpp b/apps/shared/language_controller.cpp index ee0e04084..68e047616 100644 --- a/apps/shared/language_controller.cpp +++ b/apps/shared/language_controller.cpp @@ -31,7 +31,7 @@ View * LanguageController::view() { } void LanguageController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } void LanguageController::viewWillAppear() { diff --git a/apps/shared/layout_field_delegate.h b/apps/shared/layout_field_delegate.h index fb30f6afd..042d7dfe2 100644 --- a/apps/shared/layout_field_delegate.h +++ b/apps/shared/layout_field_delegate.h @@ -14,7 +14,7 @@ public: void layoutFieldDidChangeSize(LayoutField * layoutField) override; protected: ExpressionFieldDelegateApp * expressionFieldDelegateApp() const { - return static_cast(::app()); + return static_cast(Container::activeApp()); } }; diff --git a/apps/shared/list_parameter_controller.cpp b/apps/shared/list_parameter_controller.cpp index 479d13741..27c11745f 100644 --- a/apps/shared/list_parameter_controller.cpp +++ b/apps/shared/list_parameter_controller.cpp @@ -21,7 +21,7 @@ const char * ListParameterController::title() { } void ListParameterController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } void ListParameterController::viewWillAppear() { diff --git a/apps/shared/message_controller.cpp b/apps/shared/message_controller.cpp index cab2151c5..6cff6e98b 100644 --- a/apps/shared/message_controller.cpp +++ b/apps/shared/message_controller.cpp @@ -8,7 +8,7 @@ MessageController::MessageController(I18n::Message * messages, KDColor * colors, bool MessageController::handleEvent(Ion::Events::Event event) { if (event != Ion::Events::Back && event != Ion::Events::OnOff && event != Ion::Events::Home) { - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } return false; diff --git a/apps/shared/scrollable_exact_approximate_expressions_cell.cpp b/apps/shared/scrollable_exact_approximate_expressions_cell.cpp index cb88f06b1..a3f912ea2 100644 --- a/apps/shared/scrollable_exact_approximate_expressions_cell.cpp +++ b/apps/shared/scrollable_exact_approximate_expressions_cell.cpp @@ -32,7 +32,7 @@ void ScrollableExactApproximateExpressionsCell::reloadScroll() { void ScrollableExactApproximateExpressionsCell::didBecomeFirstResponder() { m_view.setSelectedSubviewPosition(ScrollableExactApproximateExpressionsView::SubviewPosition::Left); - app()->setFirstResponder(&m_view); + Container::activeApp()->setFirstResponder(&m_view); } int ScrollableExactApproximateExpressionsCell::numberOfSubviews() const { diff --git a/apps/shared/store_controller.cpp b/apps/shared/store_controller.cpp index 168d0805e..02d57849e 100644 --- a/apps/shared/store_controller.cpp +++ b/apps/shared/store_controller.cpp @@ -36,7 +36,7 @@ void StoreController::ContentView::displayFormulaInput(bool display) { } void StoreController::ContentView::didBecomeFirstResponder() { - app()->setFirstResponder(m_displayFormulaInputView ? static_cast(&m_formulaInputView) : static_cast(&m_dataView)); + Container::activeApp()->setFirstResponder(m_displayFormulaInputView ? static_cast(&m_formulaInputView) : static_cast(&m_dataView)); } View * StoreController::ContentView::subviewAtIndex(int index) { @@ -86,12 +86,12 @@ bool StoreController::textFieldDidFinishEditing(TextField * textField, const cha // Handle formula input Expression expression = Expression::Parse(textField->text()); if (expression.isUninitialized()) { - app()->displayWarning(I18n::Message::SyntaxError); + Container::activeApp()->displayWarning(I18n::Message::SyntaxError); return false; } m_contentView.displayFormulaInput(false); if (fillColumnWithFormula(expression)) { - app()->setFirstResponder(&m_contentView); + Container::activeApp()->setFirstResponder(&m_contentView); } return true; } @@ -107,7 +107,7 @@ bool StoreController::textFieldDidFinishEditing(TextField * textField, const cha bool StoreController::textFieldDidAbortEditing(TextField * textField) { if (textField == m_contentView.formulaInputView()->textField()) { m_contentView.displayFormulaInput(false); - app()->setFirstResponder(&m_contentView); + Container::activeApp()->setFirstResponder(&m_contentView); return true; } return EditableCellTableViewController::textFieldDidAbortEditing(textField); @@ -185,7 +185,7 @@ bool StoreController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { selectableTableView()->deselectTable(); assert(selectedRow() == -1); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } assert(selectedColumn() >= 0 && selectedColumn() < numberOfColumns()); @@ -213,7 +213,7 @@ void StoreController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); } EditableCellTableViewController::didBecomeFirstResponder(); - app()->setFirstResponder(&m_contentView); + Container::activeApp()->setFirstResponder(&m_contentView); } Responder * StoreController::tabController() const { @@ -289,7 +289,7 @@ bool StoreController::privateFillColumnWithFormula(Expression formula, Expressio // Compute the new value using the formula double evaluation = PoincareHelpers::ApproximateToScalar(formula, *store); if (std::isnan(evaluation) || std::isinf(evaluation)) { - app()->displayWarning(I18n::Message::DataNotSuitable); + Container::activeApp()->displayWarning(I18n::Message::DataNotSuitable); return false; } } diff --git a/apps/shared/store_parameter_controller.cpp b/apps/shared/store_parameter_controller.cpp index 4a0362ead..752cdad26 100644 --- a/apps/shared/store_parameter_controller.cpp +++ b/apps/shared/store_parameter_controller.cpp @@ -26,7 +26,7 @@ const char * StoreParameterController::title() { void StoreParameterController::didBecomeFirstResponder() { selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool StoreParameterController::handleEvent(Ion::Events::Event event) { diff --git a/apps/shared/sum_graph_controller.cpp b/apps/shared/sum_graph_controller.cpp index b08914e53..948a9cde3 100644 --- a/apps/shared/sum_graph_controller.cpp +++ b/apps/shared/sum_graph_controller.cpp @@ -44,14 +44,14 @@ void SumGraphController::viewWillAppear() { void SumGraphController::didEnterResponderChain(Responder * previousFirstResponder) { - app()->setFirstResponder(m_legendView.textField()); + Container::activeApp()->setFirstResponder(m_legendView.textField()); } bool SumGraphController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Back && m_step != Step::FirstParameter) { m_step = (Step)((int)m_step-1); if (m_step == Step::SecondParameter) { - app()->setFirstResponder(m_legendView.textField()); + Container::activeApp()->setFirstResponder(m_legendView.textField()); m_graphView->setAreaHighlightColor(false); m_graphView->setCursorView(&m_cursorView); } @@ -95,7 +95,7 @@ bool SumGraphController::textFieldDidFinishEditing(TextField * textField, const return false; } if ((m_step == Step::SecondParameter && floatBody < m_startSum) || !moveCursorHorizontallyToPosition(floatBody)) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } return handleEnter(); @@ -125,7 +125,7 @@ bool SumGraphController::handleEnter() { } else { m_graphView->setAreaHighlightColor(true); m_graphView->setCursorView(nullptr); - app()->setFirstResponder(this); + Container::activeApp()->setFirstResponder(this); } m_step = (Step)((int)m_step+1); reloadBannerView(); diff --git a/apps/shared/tab_table_controller.cpp b/apps/shared/tab_table_controller.cpp index e32cfadea..a669e001d 100644 --- a/apps/shared/tab_table_controller.cpp +++ b/apps/shared/tab_table_controller.cpp @@ -8,7 +8,7 @@ TabTableController::TabTableController(Responder * parentResponder) : } void TabTableController::didBecomeFirstResponder() { - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); } void TabTableController::viewWillAppear() { diff --git a/apps/shared/text_field_delegate.h b/apps/shared/text_field_delegate.h index a434c59f2..bc148e95a 100644 --- a/apps/shared/text_field_delegate.h +++ b/apps/shared/text_field_delegate.h @@ -11,7 +11,7 @@ public: bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; protected: TextFieldDelegateApp * textFieldDelegateApp() const { - return static_cast(::app()); + return static_cast(Container::activeApp()); } }; diff --git a/apps/shared/values_controller.cpp b/apps/shared/values_controller.cpp index d2a1f7691..a260eda64 100644 --- a/apps/shared/values_controller.cpp +++ b/apps/shared/values_controller.cpp @@ -79,7 +79,7 @@ bool ValuesController::handleEvent(Ion::Events::Event event) { if (selectedRow() == -1) { header()->setSelectedButton(-1); selectableTableView()->selectCellAtLocation(0,0); - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); return true; } return false; @@ -88,7 +88,7 @@ bool ValuesController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { if (selectedRow() == -1) { header()->setSelectedButton(-1); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } selectableTableView()->deselectTable(); diff --git a/apps/shared/values_function_parameter_controller.cpp b/apps/shared/values_function_parameter_controller.cpp index 4f68ad405..6c6c6ac8a 100644 --- a/apps/shared/values_function_parameter_controller.cpp +++ b/apps/shared/values_function_parameter_controller.cpp @@ -15,7 +15,7 @@ void ValuesFunctionParameterController::viewWillAppear() { void ValuesFunctionParameterController::didBecomeFirstResponder() { m_selectableTableView.reloadData(); selectCellAtLocation(0, 0); - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } } diff --git a/apps/shared/values_parameter_controller.cpp b/apps/shared/values_parameter_controller.cpp index 058b35996..88b1d2fe1 100644 --- a/apps/shared/values_parameter_controller.cpp +++ b/apps/shared/values_parameter_controller.cpp @@ -38,7 +38,7 @@ void ValuesParameterController::didBecomeFirstResponder() { if (selectedRow() < 0) { selectCellAtLocation(0, 0); } - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool ValuesParameterController::handleEvent(Ion::Events::Event event) { diff --git a/apps/solver/app.h b/apps/solver/app.h index cf62f7b5b..9214b680a 100644 --- a/apps/solver/app.h +++ b/apps/solver/app.h @@ -46,7 +46,7 @@ private: }; inline App * app() { - return static_cast(::app()); + return static_cast(Container::activeApp()); } } diff --git a/apps/solver/equation_list_view.cpp b/apps/solver/equation_list_view.cpp index a9fb8ab2c..7253374cd 100644 --- a/apps/solver/equation_list_view.cpp +++ b/apps/solver/equation_list_view.cpp @@ -44,7 +44,7 @@ View * EquationListView::subviewAtIndex(int index) { } void EquationListView::didBecomeFirstResponder() { - app()->setFirstResponder(&m_listView); + Container::activeApp()->setFirstResponder(&m_listView); } void EquationListView::layoutSubviews() { diff --git a/apps/solver/equation_models_parameter_controller.cpp b/apps/solver/equation_models_parameter_controller.cpp index 67382c589..f8c9339a3 100644 --- a/apps/solver/equation_models_parameter_controller.cpp +++ b/apps/solver/equation_models_parameter_controller.cpp @@ -42,7 +42,7 @@ void EquationModelsParameterController::viewWillAppear() { } void EquationModelsParameterController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_selectableTableView); + Container::activeApp()->setFirstResponder(&m_selectableTableView); } bool EquationModelsParameterController::handleEvent(Ion::Events::Event event) { @@ -53,7 +53,7 @@ bool EquationModelsParameterController::handleEvent(Ion::Events::Event event) { } assert(error == Ion::Storage::Record::ErrorStatus::None); m_listController->editSelectedRecordWithText(k_models[selectedRow()]); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); m_listController->editExpression(Ion::Events::OK); return true; } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index 3125c9188..4efaf10ae 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -81,7 +81,7 @@ bool ListController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up && selectedRow() == -1) { footer()->setSelectedButton(-1); selectableTableView()->selectCellAtLocation(0, numberOfRows()-1); - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); return true; } if (event == Ion::Events::Down) { @@ -105,7 +105,7 @@ void ListController::didBecomeFirstResponder() { selectCellAtLocation(selectedColumn(), numberOfRows()-1); } footer()->setSelectedButton(-1); - app()->setFirstResponder(selectableTableView()); + Container::activeApp()->setFirstResponder(selectableTableView()); } void ListController::didEnterResponderChain(Responder * previousFirstResponder) { @@ -132,7 +132,7 @@ bool ListController::textFieldDidReceiveEvent(TextField * textField, Ion::Events textField->handleEvent(Ion::Events::ShiftRight); textField->handleEventWithText("=0"); if (!textRepresentsAnEquality(textField->text())) { - app()->displayWarning(I18n::Message::RequireEquation); + Container::activeApp()->displayWarning(I18n::Message::RequireEquation); return true; } } @@ -149,7 +149,7 @@ bool ListController::layoutFieldDidReceiveEvent(LayoutField * layoutField, Ion:: layoutField->handleEvent(Ion::Events::ShiftRight); layoutField->handleEventWithText("=0"); if (!layoutRepresentsAnEquality(layoutField->layout())) { - app()->displayWarning(I18n::Message::RequireEquation); + Container::activeApp()->displayWarning(I18n::Message::RequireEquation); return true; } } @@ -172,22 +172,22 @@ bool ListController::layoutFieldDidFinishEditing(LayoutField * layoutField, Poin void ListController::resolveEquations() { if (m_equationStore->numberOfDefinedModels() == 0) { - app()->displayWarning(I18n::Message::EnterEquation); + Container::activeApp()->displayWarning(I18n::Message::EnterEquation); return; } EquationStore::Error e = m_equationStore->exactSolve(textFieldDelegateApp()->localContext()); switch (e) { case EquationStore::Error::EquationUndefined: - app()->displayWarning(I18n::Message::UndefinedEquation); + Container::activeApp()->displayWarning(I18n::Message::UndefinedEquation); return; case EquationStore::Error::EquationUnreal: - app()->displayWarning(I18n::Message::UnrealEquation); + Container::activeApp()->displayWarning(I18n::Message::UnrealEquation); return; case EquationStore::Error::TooManyVariables: - app()->displayWarning(I18n::Message::TooManyVariables); + Container::activeApp()->displayWarning(I18n::Message::TooManyVariables); return; case EquationStore::Error::NonLinearSystem: - app()->displayWarning(I18n::Message::NonLinearSystem); + Container::activeApp()->displayWarning(I18n::Message::NonLinearSystem); return; case EquationStore::Error::RequireApproximateSolution: { @@ -209,7 +209,7 @@ void ListController::reloadButtonMessage() { } void ListController::addEmptyModel() { - app()->displayModalViewController(&m_modelsStackController, 0.f, 0.f, Metric::CommonTopMargin, Metric::CommonRightMargin, 0, Metric::CommonLeftMargin); + Container::activeApp()->displayModalViewController(&m_modelsStackController, 0.f, 0.f, Metric::CommonTopMargin, Metric::CommonRightMargin, 0, Metric::CommonLeftMargin); } bool ListController::removeModelRow(Ion::Storage::Record record) { diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index 2da207c87..6429f3c6d 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -284,7 +284,7 @@ int SolutionsController::typeAtLocation(int i, int j) { } void SolutionsController::didBecomeFirstResponder() { - app()->setFirstResponder(m_contentView.selectableTableView()); + Container::activeApp()->setFirstResponder(m_contentView.selectableTableView()); } } diff --git a/apps/statistics/calculation_controller.cpp b/apps/statistics/calculation_controller.cpp index 1524d61c8..718d7f475 100644 --- a/apps/statistics/calculation_controller.cpp +++ b/apps/statistics/calculation_controller.cpp @@ -167,7 +167,7 @@ const char * CalculationController::title() { bool CalculationController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { selectableTableView()->deselectTable(); - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); return true; } return false; diff --git a/apps/statistics/histogram_parameter_controller.cpp b/apps/statistics/histogram_parameter_controller.cpp index 8dde871a4..6c4d7a274 100644 --- a/apps/statistics/histogram_parameter_controller.cpp +++ b/apps/statistics/histogram_parameter_controller.cpp @@ -43,7 +43,7 @@ bool HistogramParameterController::setParameterAtIndex(int parameterIndex, doubl if (parameterIndex == 0) { // The bar width cannot be negative if (f <= 0.0f) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } @@ -52,7 +52,7 @@ bool HistogramParameterController::setParameterAtIndex(int parameterIndex, doubl if (m_store->firstDrawnBarAbscissa() <= m_store->maxValue(i)+f) { break; } else if (i == DoublePairStore::k_numberOfSeries - 1) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } } @@ -67,7 +67,7 @@ bool HistogramParameterController::setParameterAtIndex(int parameterIndex, doubl } } if (maxNewNumberOfBars > Store::k_maxNumberOfBars) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } @@ -84,7 +84,7 @@ bool HistogramParameterController::setParameterAtIndex(int parameterIndex, doubl } } if (maxNewNumberOfBars > Store::k_maxNumberOfBars) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } // There should be at least one value in the drawn bin @@ -92,7 +92,7 @@ bool HistogramParameterController::setParameterAtIndex(int parameterIndex, doubl if (f <= m_store->maxValue(i)+m_store->barWidth()) { break; } else if (i == DoublePairStore::k_numberOfSeries - 1) { - app()->displayWarning(I18n::Message::ForbiddenValue); + Container::activeApp()->displayWarning(I18n::Message::ForbiddenValue); return false; } } diff --git a/apps/statistics/multiple_data_view_controller.cpp b/apps/statistics/multiple_data_view_controller.cpp index 73ed94fe9..c3c9f7d5c 100644 --- a/apps/statistics/multiple_data_view_controller.cpp +++ b/apps/statistics/multiple_data_view_controller.cpp @@ -58,7 +58,7 @@ bool MultipleDataViewController::handleEvent(Ion::Events::Event event) { multipleDataView()->selectDataView(*m_selectedSeriesIndex); highlightSelection(); } else { - app()->setFirstResponder(tabController()); + Container::activeApp()->setFirstResponder(tabController()); } reloadBannerView(); return true; diff --git a/apps/variable_box_controller.cpp b/apps/variable_box_controller.cpp index 13c790278..ff5ed82fb 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/variable_box_controller.cpp @@ -211,7 +211,7 @@ bool VariableBoxController::selectLeaf(int selectedRow) { // Handle the text sender()->handleEventWithText(nameToHandle); - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 773191188..0070adb02 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -42,8 +42,4 @@ private: virtual Timer * containerTimerAtIndex(int i); }; -inline App * app() { - return Container::activeApp(); -} - #endif diff --git a/escher/src/alternate_empty_view_controller.cpp b/escher/src/alternate_empty_view_controller.cpp index 75314077e..9dc3c33d4 100644 --- a/escher/src/alternate_empty_view_controller.cpp +++ b/escher/src/alternate_empty_view_controller.cpp @@ -67,7 +67,7 @@ bool AlternateEmptyViewController::handleEvent(Ion::Events::Event event) { void AlternateEmptyViewController::didBecomeFirstResponder() { if (!m_contentView.alternateEmptyViewDelegate()->isEmpty()) { - app()->setFirstResponder(m_contentView.mainViewController()); + Container::activeApp()->setFirstResponder(m_contentView.mainViewController()); } } diff --git a/escher/src/bank_view_controller.cpp b/escher/src/bank_view_controller.cpp index 71f26468b..0abe434d2 100644 --- a/escher/src/bank_view_controller.cpp +++ b/escher/src/bank_view_controller.cpp @@ -14,14 +14,14 @@ void BankViewController::setActiveIndex(int i) { } ViewController * upcomingVC = childAtIndex(i); upcomingVC->viewWillAppear(); - app()->setFirstResponder(upcomingVC); + Container::activeApp()->setFirstResponder(upcomingVC); childAtIndex(m_activeIndex)->viewDidDisappear(); m_activeIndex = i; m_view.setSubview(upcomingVC->view()); } void BankViewController::didEnterResponderChain(Responder * previousResponder) { - app()->setFirstResponder(activeViewController()); + Container::activeApp()->setFirstResponder(activeViewController()); } void BankViewController::initView() { diff --git a/escher/src/button_row_controller.cpp b/escher/src/button_row_controller.cpp index 6139c08a2..479d1c140 100644 --- a/escher/src/button_row_controller.cpp +++ b/escher/src/button_row_controller.cpp @@ -154,7 +154,7 @@ bool ButtonRowController::ContentView::setSelectedButton(int selectedButton) { if (m_selectedButton >= 0) { Button * button = buttonAtIndex(selectedButton); button->setHighlighted(true); - app()->setFirstResponder(button); + Container::activeApp()->setFirstResponder(button); return true; } return false; @@ -171,7 +171,7 @@ const char * ButtonRowController::title() { } void ButtonRowController::didBecomeFirstResponder(){ - app()->setFirstResponder(m_contentView.mainViewController()); + Container::activeApp()->setFirstResponder(m_contentView.mainViewController()); } int ButtonRowController::selectedButton() { diff --git a/escher/src/editable_text_cell.cpp b/escher/src/editable_text_cell.cpp index b03d6bed7..9365b40e6 100644 --- a/escher/src/editable_text_cell.cpp +++ b/escher/src/editable_text_cell.cpp @@ -51,7 +51,7 @@ void EditableTextCell::layoutSubviews() { } void EditableTextCell::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); } KDSize EditableTextCell::minimalSizeForOptimalDisplay() const { diff --git a/escher/src/even_odd_editable_text_cell.cpp b/escher/src/even_odd_editable_text_cell.cpp index 00473c504..cabf66504 100644 --- a/escher/src/even_odd_editable_text_cell.cpp +++ b/escher/src/even_odd_editable_text_cell.cpp @@ -37,5 +37,5 @@ void EvenOddEditableTextCell::layoutSubviews() { } void EvenOddEditableTextCell::didBecomeFirstResponder() { - app()->setFirstResponder(&m_editableCell); + Container::activeApp()->setFirstResponder(&m_editableCell); } diff --git a/escher/src/input_event_handler.cpp b/escher/src/input_event_handler.cpp index 8d197fb39..ee18a4025 100644 --- a/escher/src/input_event_handler.cpp +++ b/escher/src/input_event_handler.cpp @@ -12,7 +12,7 @@ bool InputEventHandler::handleBoxEvent(Ion::Events::Event event) { } if (box) { box->setSender(this); - app()->displayModalViewController(box, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin); + Container::activeApp()->displayModalViewController(box, 0.f, 0.f, Metric::PopUpTopMargin, Metric::PopUpLeftMargin, 0, Metric::PopUpRightMargin); return true; } return false; diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index 8aeccdf25..eb46f7217 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -11,7 +11,7 @@ InputViewController::ExpressionFieldController::ExpressionFieldController(Respon } void InputViewController::ExpressionFieldController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_expressionField); + Container::activeApp()->setFirstResponder(&m_expressionField); } InputViewController::InputViewController(Responder * parentResponder, ViewController * child, InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * textFieldDelegate, LayoutFieldDelegate * layoutFieldDelegate) : diff --git a/escher/src/message_table_cell_with_editable_text.cpp b/escher/src/message_table_cell_with_editable_text.cpp index 401ab0084..f64c082b8 100644 --- a/escher/src/message_table_cell_with_editable_text.cpp +++ b/escher/src/message_table_cell_with_editable_text.cpp @@ -19,7 +19,7 @@ const char * MessageTableCellWithEditableText::editedText() const { } void MessageTableCellWithEditableText::didBecomeFirstResponder() { - app()->setFirstResponder(&m_textField); + Container::activeApp()->setFirstResponder(&m_textField); } bool MessageTableCellWithEditableText::isEditing() { diff --git a/escher/src/modal_view_controller.cpp b/escher/src/modal_view_controller.cpp index 893abd648..bbba5cceb 100644 --- a/escher/src/modal_view_controller.cpp +++ b/escher/src/modal_view_controller.cpp @@ -117,11 +117,11 @@ void ModalViewController::displayModalViewController(ViewController * vc, float KDCoordinate topMargin, KDCoordinate leftMargin, KDCoordinate bottomMargin, KDCoordinate rightMargin) { m_currentModalViewController = vc; vc->setParentResponder(this); - m_previousResponder = app()->firstResponder(); + m_previousResponder = Container::activeApp()->firstResponder(); m_currentModalViewController->initView(); m_contentView.presentModalView(vc->view(), verticalAlignment, horizontalAlignment, topMargin, leftMargin, bottomMargin, rightMargin); m_currentModalViewController->viewWillAppear(); - app()->setFirstResponder(vc); + Container::activeApp()->setFirstResponder(vc); } void ModalViewController::reloadModalViewController() { @@ -130,13 +130,13 @@ void ModalViewController::reloadModalViewController() { void ModalViewController::dismissModalViewController() { m_currentModalViewController->viewDidDisappear(); - app()->setFirstResponder(m_previousResponder); + Container::activeApp()->setFirstResponder(m_previousResponder); m_contentView.dismissModalView(); m_currentModalViewController = nullptr; } void ModalViewController::didBecomeFirstResponder() { - app()->setFirstResponder(m_regularViewController); + Container::activeApp()->setFirstResponder(m_regularViewController); } bool ModalViewController::handleEvent(Ion::Events::Event event) { diff --git a/escher/src/nested_menu_controller.cpp b/escher/src/nested_menu_controller.cpp index afac10050..2ba845a67 100644 --- a/escher/src/nested_menu_controller.cpp +++ b/escher/src/nested_menu_controller.cpp @@ -79,7 +79,7 @@ View * NestedMenuController::ListController::view() { void NestedMenuController::ListController::didBecomeFirstResponder() { m_selectableTableView->reloadData(); m_selectableTableView->selectCellAtLocation(0, m_firstSelectedRow); - app()->setFirstResponder(m_selectableTableView); + Container::activeApp()->setFirstResponder(m_selectableTableView); } void NestedMenuController::ListController::setFirstSelectedRow(int firstSelectedRow) { @@ -103,7 +103,7 @@ bool NestedMenuController::handleEvent(Ion::Events::Event event) { } void NestedMenuController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_listController); + Container::activeApp()->setFirstResponder(&m_listController); } void NestedMenuController::viewWillAppear() { @@ -155,7 +155,7 @@ bool NestedMenuController::handleEventForRow(Ion::Events::Event event, int rowIn bool NestedMenuController::selectSubMenu(int selectedRow) { m_stack.push(selectedRow, m_selectableTableView.contentOffset().y()); m_listController.setFirstSelectedRow(0); - app()->setFirstResponder(&m_listController); + Container::activeApp()->setFirstResponder(&m_listController); return true; } @@ -165,6 +165,6 @@ bool NestedMenuController::returnToPreviousMenu() { m_listController.setFirstSelectedRow(state.selectedRow()); KDPoint scroll = m_selectableTableView.contentOffset(); m_selectableTableView.setContentOffset(KDPoint(scroll.x(), state.verticalScroll())); - app()->setFirstResponder(&m_listController); + Container::activeApp()->setFirstResponder(&m_listController); return true; } diff --git a/escher/src/selectable_table_view.cpp b/escher/src/selectable_table_view.cpp index d5c6005b8..24169c068 100644 --- a/escher/src/selectable_table_view.cpp +++ b/escher/src/selectable_table_view.cpp @@ -104,11 +104,7 @@ bool SelectableTableView::selectCellAtLocation(int i, int j, bool setFirstRespon if (cell) { // Update first responder if ((i != previousX || j != previousY) && setFirstResponder) { - if (cell->responder()) { - app()->setFirstResponder(cell->responder()); - } else { - app()->setFirstResponder(this); - } + Container::activeApp()->setFirstResponder(cell->responder() ? cell->responder() : this); } } diff --git a/escher/src/stack_view_controller.cpp b/escher/src/stack_view_controller.cpp index 0facbf629..f19ee1261 100644 --- a/escher/src/stack_view_controller.cpp +++ b/escher/src/stack_view_controller.cpp @@ -137,12 +137,12 @@ void StackViewController::setupActiveViewController() { m_view.setContentView(vc->view()); vc->viewWillAppear(); vc->setParentResponder(this); - app()->setFirstResponder(vc); + Container::activeApp()->setFirstResponder(vc); } void StackViewController::didBecomeFirstResponder() { ViewController * vc = m_childrenFrame[m_numberOfChildren-1].viewController(); - app()->setFirstResponder(vc); + Container::activeApp()->setFirstResponder(vc); } bool StackViewController::handleEvent(Ion::Events::Event event) { diff --git a/escher/src/tab_view_controller.cpp b/escher/src/tab_view_controller.cpp index 7c09780d2..f7ad3c48d 100644 --- a/escher/src/tab_view_controller.cpp +++ b/escher/src/tab_view_controller.cpp @@ -75,16 +75,14 @@ int TabViewController::activeTab() const { } bool TabViewController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::Back) { - if (app()->firstResponder() != this) { - app()->setFirstResponder(this); + App * app = Container::activeApp(); + if (app->firstResponder() != this) { + if (event == Ion::Events::Back) { + app->setFirstResponder(this); return true; } return false; } - if (app()->firstResponder() != this) { - return false; - } if (event == Ion::Events::Left) { if (m_dataSource->selectedTab() > 0) { setSelectedTab(m_dataSource->selectedTab()-1); @@ -116,7 +114,7 @@ void TabViewController::setActiveTab(int8_t i) { m_children[i]->viewWillAppear(); m_view.m_tabView.setActiveIndex(i); } - app()->setFirstResponder(activeVC); + Container::activeApp()->setFirstResponder(activeVC); if (i != m_dataSource->activeTab()) { m_children[m_dataSource->activeTab()]->viewDidDisappear(); m_dataSource->setActiveTab(i); @@ -132,7 +130,7 @@ void TabViewController::setSelectedTab(int8_t i) { } void TabViewController::didEnterResponderChain(Responder * previousResponder) { - app()->setFirstResponder(activeViewController()); + Container::activeApp()->setFirstResponder(activeViewController()); } void TabViewController::didBecomeFirstResponder() { diff --git a/escher/src/warning_controller.cpp b/escher/src/warning_controller.cpp index 1030d922d..07bc18f22 100644 --- a/escher/src/warning_controller.cpp +++ b/escher/src/warning_controller.cpp @@ -83,6 +83,6 @@ bool WarningController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::USBPlug || event == Ion::Events::USBEnumeration) { return false; } - app()->dismissModalViewController(); + Container::activeApp()->dismissModalViewController(); return true; } From eb6d6979279a41aa390ac77dbace809225988bb0 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 13:27:15 +0200 Subject: [PATCH 082/111] [apps] Make app accessors static members of App classes --- apps/calculation/app.h | 7 +++---- apps/calculation/history_controller.cpp | 2 +- apps/calculation/history_view_cell.cpp | 9 +++++---- apps/code/app.h | 7 +++---- apps/code/console_controller.cpp | 4 ++-- apps/code/editor_controller.cpp | 4 ++-- apps/code/menu_controller.cpp | 2 +- apps/code/variable_box_controller.cpp | 2 +- apps/graph/app.h | 7 +++---- apps/graph/graph/calculation_graph_controller.cpp | 2 +- apps/graph/graph/graph_controller_helper.cpp | 8 ++++---- apps/graph/graph/tangent_graph_controller.cpp | 4 ++-- apps/graph/values/derivative_parameter_controller.cpp | 2 +- apps/graph/values/function_parameter_controller.cpp | 2 +- apps/home/app.h | 7 +++---- apps/home/controller.cpp | 2 +- apps/probability/app.h | 7 +++---- apps/probability/calculation_controller.cpp | 2 +- apps/probability/law_controller.cpp | 2 +- apps/probability/parameters_controller.cpp | 2 +- apps/regression/app.h | 7 +++---- apps/regression/graph_options_controller.cpp | 2 +- apps/regression/store_parameter_controller.cpp | 2 +- apps/sequence/app.h | 7 +++---- apps/sequence/list/list_controller.cpp | 6 +++--- apps/sequence/list/list_parameter_controller.cpp | 4 ++-- apps/sequence/list/type_parameter_controller.cpp | 4 ++-- apps/solver/app.h | 7 +++---- apps/solver/interval_controller.cpp | 2 +- apps/solver/list_controller.cpp | 6 +++--- apps/solver/solutions_controller.cpp | 2 +- 31 files changed, 63 insertions(+), 70 deletions(-) diff --git a/apps/calculation/app.h b/apps/calculation/app.h index aee59a7ff..2da436693 100644 --- a/apps/calculation/app.h +++ b/apps/calculation/app.h @@ -27,6 +27,9 @@ public: void tidy() override; CalculationStore m_calculationStore; }; + static App * app() { + return static_cast(Container::activeApp()); + } bool textFieldDidReceiveEvent(::TextField * textField, Ion::Events::Event event) override; bool layoutFieldDidReceiveEvent(::LayoutField * layoutField, Ion::Events::Event event) override; // TextFieldDelegateApp @@ -39,10 +42,6 @@ private: EditExpressionController m_editExpressionController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 04b63ae46..6a17e9226 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -151,7 +151,7 @@ KDCoordinate HistoryController::rowHeight(int j) { return 0; } Calculation * calculation = m_calculationStore->calculationAtIndex(j); - return calculation->height(app()->localContext(), j == selectedRow() && selectedSubviewType() == SubviewType::Output) + 4 * Metric::CommonSmallMargin; + return calculation->height(App::app()->localContext(), j == selectedRow() && selectedSubviewType() == SubviewType::Output) + 4 * Metric::CommonSmallMargin; } int HistoryController::typeAtLocation(int i, int j) { diff --git a/apps/calculation/history_view_cell.cpp b/apps/calculation/history_view_cell.cpp index 1e084c586..deb80e5bf 100644 --- a/apps/calculation/history_view_cell.cpp +++ b/apps/calculation/history_view_cell.cpp @@ -75,7 +75,7 @@ void HistoryViewCell::reloadScroll() { } void HistoryViewCell::reloadOutputSelection() { - Calculation::DisplayOutput display = m_calculation.displayOutput(app()->localContext()); + Calculation::DisplayOutput display = m_calculation.displayOutput(App::app()->localContext()); /* Select the right output according to the calculation display output. This * will reload the scroll to display the selected output. */ if (display == Calculation::DisplayOutput::ExactAndApproximate) { @@ -136,10 +136,11 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { if (m_calculationExpanded == expanded && *calculation == m_calculation) { return; } + Poincare::Context * context = App::app()->localContext(); // Memoization m_calculation = *calculation; m_calculationExpanded = expanded; - Calculation::DisplayOutput display = calculation->displayOutput(app()->localContext()); + Calculation::DisplayOutput display = calculation->displayOutput(context); m_inputView.setLayout(calculation->createInputLayout()); /* Both output expressions have to be updated at the same time. Otherwise, * when updating one layout, if the second one still points to a deleted @@ -149,13 +150,13 @@ void HistoryViewCell::setCalculation(Calculation * calculation, bool expanded) { if (display == Calculation::DisplayOutput::ExactOnly) { rightOutputLayout = calculation->createExactOutputLayout(); } else { - rightOutputLayout = calculation->createApproximateOutputLayout(app()->localContext()); + rightOutputLayout = calculation->createApproximateOutputLayout(context); if (display == Calculation::DisplayOutput::ExactAndApproximate || (display == Calculation::DisplayOutput::ExactAndApproximateToggle && expanded)) { leftOutputLayout = calculation->createExactOutputLayout(); } } m_scrollableOutputView.setLayouts(rightOutputLayout, leftOutputLayout); - I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(app()->localContext()) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; + I18n::Message equalMessage = calculation->exactAndApproximateDisplayedOutputsAreEqual(context) == Calculation::EqualSign::Equal ? I18n::Message::Equal : I18n::Message::AlmostEqual; m_scrollableOutputView.setEqualMessage(equalMessage); /* The displayed input and outputs have changed. We need to re-layout the cell diff --git a/apps/code/app.h b/apps/code/app.h index f188a175e..5b3e658b5 100644 --- a/apps/code/app.h +++ b/apps/code/app.h @@ -36,6 +36,9 @@ public: #endif ScriptStore m_scriptStore; }; + static App * app() { + return static_cast(Container::activeApp()); + } ~App(); bool prepareForExit() override { if (m_consoleController.inputRunLoopActive()) { @@ -84,10 +87,6 @@ private: VariableBoxController m_variableBoxController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index 8eb34d8fb..1ee21b9cb 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -57,7 +57,7 @@ bool ConsoleController::loadPythonEnvironment() { /* We load functions and variables names in the variable box before running * any other python code to avoid failling to load functions and variables * due to memory exhaustion. */ - app()->variableBoxController()->loadFunctionsAndVariables(); + App::app()->variableBoxController()->loadFunctionsAndVariables(); return true; } @@ -290,7 +290,7 @@ bool ConsoleController::textFieldDidReceiveEvent(TextField * textField, Ion::Eve return true; } } - return app()->textInputDidReceiveEvent(textField, event); + return App::app()->textInputDidReceiveEvent(textField, event); } bool ConsoleController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { diff --git a/apps/code/editor_controller.cpp b/apps/code/editor_controller.cpp index 4c59d49c6..011584f57 100644 --- a/apps/code/editor_controller.cpp +++ b/apps/code/editor_controller.cpp @@ -58,7 +58,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: saveScript(); return false; } - if (app()->textInputDidReceiveEvent(textArea, event)) { + if (App::app()->textInputDidReceiveEvent(textArea, event)) { return true; } if (event == Ion::Events::EXE) { @@ -109,7 +109,7 @@ bool EditorController::textAreaDidReceiveEvent(TextArea * textArea, Ion::Events: } VariableBoxController * EditorController::variableBoxForInputEventHandler(InputEventHandler * textInput) { - VariableBoxController * varBox = app()->variableBoxController(); + VariableBoxController * varBox = App::app()->variableBoxController(); varBox->loadFunctionsAndVariables(); return varBox; } diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index 25bcf67aa..381d13e23 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -36,7 +36,7 @@ MenuController::MenuController(Responder * parentResponder, App * pythonDelegate } ConsoleController * MenuController::consoleController() { - return app()->consoleController(); + return App::app()->consoleController(); } StackViewController * MenuController::stackViewController() { diff --git a/apps/code/variable_box_controller.cpp b/apps/code/variable_box_controller.cpp index 88f981942..964656dfc 100644 --- a/apps/code/variable_box_controller.cpp +++ b/apps/code/variable_box_controller.cpp @@ -33,7 +33,7 @@ void VariableBoxController::didEnterResponderChain(Responder * previousFirstResp * environment where Python has already been inited. This way, we do not * deinit Python when leaving the VariableBoxController, so we do not lose the * environment that was loaded when entering the VariableBoxController. */ - assert(app()->pythonIsInited()); + assert(App::app()->pythonIsInited()); } static bool shouldAddObject(const char * name, int maxLength) { diff --git a/apps/graph/app.h b/apps/graph/app.h index d3f7a5314..52a73863c 100644 --- a/apps/graph/app.h +++ b/apps/graph/app.h @@ -30,6 +30,9 @@ public: CartesianFunctionStore m_functionStore; Shared::InteractiveCurveViewRange m_graphRange; }; + static App * app() { + return static_cast(Container::activeApp()); + } InputViewController * inputViewController() override; char XNT() override; NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; @@ -52,10 +55,6 @@ private: InputViewController m_inputViewController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/graph/graph/calculation_graph_controller.cpp b/apps/graph/graph/calculation_graph_controller.cpp index dafde5ae7..b3c857a0b 100644 --- a/apps/graph/graph/calculation_graph_controller.cpp +++ b/apps/graph/graph/calculation_graph_controller.cpp @@ -52,7 +52,7 @@ Expression::Coordinate2D CalculationGraphController::computeNewPointOfInteresetF } CartesianFunctionStore * CalculationGraphController::functionStore() const { - return app()->functionStore(); + return App::app()->functionStore(); } bool CalculationGraphController::handleLeftRightEvent(Ion::Events::Event event) { diff --git a/apps/graph/graph/graph_controller_helper.cpp b/apps/graph/graph/graph_controller_helper.cpp index ad4f18a2a..c74fc2df4 100644 --- a/apps/graph/graph/graph_controller_helper.cpp +++ b/apps/graph/graph/graph_controller_helper.cpp @@ -10,23 +10,23 @@ using namespace Poincare; namespace Graph { bool GraphControllerHelper::privateMoveCursorHorizontally(Shared::CurveViewCursor * cursor, int direction, Shared::InteractiveCurveViewRange * range, int numberOfStepsInGradUnit, Ion::Storage::Record record) { - ExpiringPointer function = app()->functionStore()->modelForRecord(record); + ExpiringPointer function = App::app()->functionStore()->modelForRecord(record); double xCursorPosition = cursor->x(); double x = direction > 0 ? xCursorPosition + range->xGridUnit()/numberOfStepsInGradUnit : xCursorPosition - range->xGridUnit()/numberOfStepsInGradUnit; - double y = function->evaluateAtAbscissa(x, app()->localContext()); + double y = function->evaluateAtAbscissa(x, App::app()->localContext()); cursor->moveTo(x, y); return true; } void GraphControllerHelper::reloadDerivativeInBannerViewForCursorOnFunction(Shared::CurveViewCursor * cursor, Ion::Storage::Record record) { - ExpiringPointer function = app()->functionStore()->modelForRecord(record); + ExpiringPointer function = App::app()->functionStore()->modelForRecord(record); constexpr size_t bufferSize = FunctionBannerDelegate::k_maxNumberOfCharacters+PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits); char buffer[bufferSize]; const char * space = " "; int numberOfChar = function->derivativeNameWithArgument(buffer, bufferSize, CartesianFunction::Symbol()); const char * legend = "="; numberOfChar += strlcpy(buffer+numberOfChar, legend, bufferSize-numberOfChar); - double y = function->approximateDerivative(cursor->x(), app()->localContext()); + double y = function->approximateDerivative(cursor->x(), App::app()->localContext()); numberOfChar += PoincareHelpers::ConvertFloatToText(y, buffer + numberOfChar, bufferSize-numberOfChar, Constant::ShortNumberOfSignificantDigits); strlcpy(buffer+numberOfChar, space, bufferSize-numberOfChar); bannerView()->derivativeView()->setText(buffer); diff --git a/apps/graph/graph/tangent_graph_controller.cpp b/apps/graph/graph/tangent_graph_controller.cpp index 33e9589d1..82e9ad4cb 100644 --- a/apps/graph/graph/tangent_graph_controller.cpp +++ b/apps/graph/graph/tangent_graph_controller.cpp @@ -44,7 +44,7 @@ bool TangentGraphController::textFieldDidFinishEditing(TextField * textField, co if (myApp->hasUndefinedValue(text, floatBody)) { return false; } - ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); + ExpiringPointer function = App::app()->functionStore()->modelForRecord(m_record); double y = function->evaluateAtAbscissa(floatBody, myApp->localContext()); m_cursor->moveTo(floatBody, y); interactiveCurveViewRange()->panToMakePointVisible(m_cursor->x(), m_cursor->y(), cursorTopMarginRatio(), k_cursorRightMarginRatio, cursorBottomMarginRatio(), k_cursorLeftMarginRatio); @@ -70,7 +70,7 @@ void TangentGraphController::reloadBannerView() { const char * legend = "a="; int legendLength = strlcpy(buffer, legend, bufferSize); - ExpiringPointer function = app()->functionStore()->modelForRecord(m_record); + ExpiringPointer function = App::app()->functionStore()->modelForRecord(m_record); double y = function->approximateDerivative(m_cursor->x(), context); PoincareHelpers::ConvertFloatToText(y, buffer + legendLength, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::MediumNumberOfSignificantDigits), Constant::MediumNumberOfSignificantDigits); m_bannerView->aView()->setText(buffer); diff --git a/apps/graph/values/derivative_parameter_controller.cpp b/apps/graph/values/derivative_parameter_controller.cpp index 18f6188fd..e2725fcac 100644 --- a/apps/graph/values/derivative_parameter_controller.cpp +++ b/apps/graph/values/derivative_parameter_controller.cpp @@ -82,7 +82,7 @@ KDCoordinate DerivativeParameterController::cellHeight() { } CartesianFunctionStore * DerivativeParameterController::functionStore() { - return app()->functionStore(); + return App::app()->functionStore(); } } diff --git a/apps/graph/values/function_parameter_controller.cpp b/apps/graph/values/function_parameter_controller.cpp index a95d14373..be0775ff5 100644 --- a/apps/graph/values/function_parameter_controller.cpp +++ b/apps/graph/values/function_parameter_controller.cpp @@ -70,7 +70,7 @@ void FunctionParameterController::willDisplayCellForIndex(HighlightCell * cell, } ExpiringPointer FunctionParameterController::function() { - return app()->functionStore()->modelForRecord(m_record); + return App::app()->functionStore()->modelForRecord(m_record); } } diff --git a/apps/home/app.h b/apps/home/app.h index 22ab0e4fd..a19ea571b 100644 --- a/apps/home/app.h +++ b/apps/home/app.h @@ -18,6 +18,9 @@ public: App * unpack(Container * container) override; Descriptor * descriptor() override; }; + static App * app() { + return static_cast(Container::activeApp()); + } Snapshot * snapshot() const { return static_cast(::App::snapshot()); } @@ -26,10 +29,6 @@ private: Controller m_controller; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/home/controller.cpp b/apps/home/controller.cpp index 185a842fb..171197381 100644 --- a/apps/home/controller.cpp +++ b/apps/home/controller.cpp @@ -162,7 +162,7 @@ void Controller::tableViewDidChangeSelection(SelectableTableView * t, int previo } SelectableTableViewDataSource * Controller::selectionDataSource() const { - return app()->snapshot(); + return App::app()->snapshot(); } } diff --git a/apps/probability/app.h b/apps/probability/app.h index 59841f1f1..1bb342d42 100644 --- a/apps/probability/app.h +++ b/apps/probability/app.h @@ -54,6 +54,9 @@ public: char m_calculation[k_calculationSize]; Page m_activePage; }; + static App * app() { + return static_cast(Container::activeApp()); + } Snapshot * snapshot() const { return static_cast(::App::snapshot()); } private: App(Snapshot * snapshot); @@ -63,10 +66,6 @@ private: StackViewController m_stackViewController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/probability/calculation_controller.cpp b/apps/probability/calculation_controller.cpp index dd86480c1..b0ced6242 100644 --- a/apps/probability/calculation_controller.cpp +++ b/apps/probability/calculation_controller.cpp @@ -79,7 +79,7 @@ CalculationController::CalculationController(Responder * parentResponder, InputE } void CalculationController::didEnterResponderChain(Responder * previousResponder) { - app()->snapshot()->setActivePage(App::Snapshot::Page::Calculations); + App::app()->snapshot()->setActivePage(App::Snapshot::Page::Calculations); updateTitle(); reloadLawCurveView(); m_selectableTableView.reloadData(); diff --git a/apps/probability/law_controller.cpp b/apps/probability/law_controller.cpp index 14ae76ee4..feee8f25a 100644 --- a/apps/probability/law_controller.cpp +++ b/apps/probability/law_controller.cpp @@ -73,7 +73,7 @@ void Probability::LawController::viewWillAppear() { } void Probability::LawController::didBecomeFirstResponder() { - app()->snapshot()->setActivePage(App::Snapshot::Page::Law); + App::app()->snapshot()->setActivePage(App::Snapshot::Page::Law); if (selectedRow() == -1) { selectCellAtLocation(0, 0); } else { diff --git a/apps/probability/parameters_controller.cpp b/apps/probability/parameters_controller.cpp index eaeddf52a..5d5741ad3 100644 --- a/apps/probability/parameters_controller.cpp +++ b/apps/probability/parameters_controller.cpp @@ -99,7 +99,7 @@ void ParametersController::reinitCalculation() { } void ParametersController::didBecomeFirstResponder() { - app()->snapshot()->setActivePage(App::Snapshot::Page::Parameters); + App::app()->snapshot()->setActivePage(App::Snapshot::Page::Parameters); FloatParameterController::didBecomeFirstResponder(); } diff --git a/apps/regression/app.h b/apps/regression/app.h index ebac8db7a..3e5ba95c8 100644 --- a/apps/regression/app.h +++ b/apps/regression/app.h @@ -40,6 +40,9 @@ public: uint32_t m_rangeVersion; int m_selectedSeriesIndex; }; + static App * app() { + return static_cast(Container::activeApp()); + } RegressionController * regressionController() { return &m_regressionController; } private: App(Snapshot * snapshot); @@ -57,10 +60,6 @@ private: RegressionController m_regressionController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/regression/graph_options_controller.cpp b/apps/regression/graph_options_controller.cpp index b61e489a0..2e2567a33 100644 --- a/apps/regression/graph_options_controller.cpp +++ b/apps/regression/graph_options_controller.cpp @@ -41,7 +41,7 @@ void GraphOptionsController::viewWillAppear() { bool GraphOptionsController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) { if (selectedRow() == numberOfRows() -1) { - RegressionController * regressionController = app()->regressionController(); + RegressionController * regressionController = App::app()->regressionController(); regressionController->setSeries(m_graphController->selectedSeriesIndex()); StackViewController * stack = static_cast(parentResponder()); stack->push(regressionController); diff --git a/apps/regression/store_parameter_controller.cpp b/apps/regression/store_parameter_controller.cpp index 07d5095a9..322c71bd7 100644 --- a/apps/regression/store_parameter_controller.cpp +++ b/apps/regression/store_parameter_controller.cpp @@ -20,7 +20,7 @@ void StoreParameterController::viewWillAppear() { bool StoreParameterController::handleEvent(Ion::Events::Event event) { if ((event == Ion::Events::OK || event == Ion::Events::EXE || event == Ion::Events::Right) && selectedRow() == numberOfRows() - 1) { - RegressionController * regressionController = app()->regressionController(); + RegressionController * regressionController = App::app()->regressionController(); regressionController->setSeries(m_series); StackViewController * stack = static_cast(parentResponder()); stack->push(regressionController); diff --git a/apps/sequence/app.h b/apps/sequence/app.h index 2208cc095..ecfb28ab2 100644 --- a/apps/sequence/app.h +++ b/apps/sequence/app.h @@ -33,6 +33,9 @@ public: SequenceStore m_sequenceStore; CurveViewRange m_graphRange; }; + static App * app() { + return static_cast(Container::activeApp()); + } InputViewController * inputViewController() override; // TODO: override variableBoxForInputEventHandler to lock sequence in the variable box once they appear there // NestedMenuController * variableBoxForInputEventHandler(InputEventHandler * textInput) override; @@ -58,10 +61,6 @@ private: InputViewController m_inputViewController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/sequence/list/list_controller.cpp b/apps/sequence/list/list_controller.cpp index 4b600141d..b9a1b71f8 100644 --- a/apps/sequence/list/list_controller.cpp +++ b/apps/sequence/list/list_controller.cpp @@ -109,7 +109,7 @@ void ListController::editExpression(int sequenceDefinition, Ion::Events::Event e } InputViewController * inputController = Shared::FunctionApp::app()->inputViewController(); // Invalidate the sequences context cache - app()->localContext()->resetCache(); + App::app()->localContext()->resetCache(); switch (sequenceDefinition) { case 0: inputController->edit(this, event, this, initialText, @@ -267,7 +267,7 @@ void ListController::editExpression(Ion::Events::Event event) { void ListController::reinitSelectedExpression(ExpiringPointer model) { // Invalidate the sequences context cache - app()->localContext()->resetCache(); + App::app()->localContext()->resetCache(); Sequence * sequence = static_cast(model.pointer()); switch (sequenceDefinitionForRow(selectedRow())) { case 1: @@ -295,7 +295,7 @@ void ListController::reinitSelectedExpression(ExpiringPointerlocalContext()->resetCache(); + App::app()->localContext()->resetCache(); return true; } diff --git a/apps/sequence/list/list_parameter_controller.cpp b/apps/sequence/list/list_parameter_controller.cpp index 01958722a..347334ac9 100644 --- a/apps/sequence/list/list_parameter_controller.cpp +++ b/apps/sequence/list/list_parameter_controller.cpp @@ -56,7 +56,7 @@ bool ListParameterController::handleEvent(Ion::Events::Event event) { #else if (selectedRowIndex == 2+hasAdditionalRow) { #endif - app()->localContext()->resetCache(); + App::app()->localContext()->resetCache(); return handleEnterOnRow(selectedRowIndex-hasAdditionalRow-1); } } @@ -82,7 +82,7 @@ bool ListParameterController::textFieldDidFinishEditing(TextField * textField, c } sequence()->setInitialRank(index); // Invalidate sequence context cache when changing sequence type - app()->localContext()->resetCache(); + App::app()->localContext()->resetCache(); m_selectableTableView.reloadCellAtLocation(0, selectedRow()); m_selectableTableView.handleEvent(event); return true; diff --git a/apps/sequence/list/type_parameter_controller.cpp b/apps/sequence/list/type_parameter_controller.cpp index 637a79055..40a7c30b6 100644 --- a/apps/sequence/list/type_parameter_controller.cpp +++ b/apps/sequence/list/type_parameter_controller.cpp @@ -60,7 +60,7 @@ bool TypeParameterController::handleEvent(Ion::Events::Event event) { m_listController->selectPreviousNewSequenceCell(); sequence()->setType(sequenceType); // Invalidate sequence context cache when changing sequence type - app()->localContext()->resetCache(); + App::app()->localContext()->resetCache(); // Reset the first index if the new type is "Explicit" if (sequenceType == Sequence::Type::Explicit) { sequence()->setInitialRank(0); @@ -135,7 +135,7 @@ void TypeParameterController::setRecord(Ion::Storage::Record record) { } SequenceStore * TypeParameterController::sequenceStore() { - return app()->functionStore(); + return App::app()->functionStore(); } StackViewController * TypeParameterController::stackController() const { diff --git a/apps/solver/app.h b/apps/solver/app.h index 9214b680a..e80015d25 100644 --- a/apps/solver/app.h +++ b/apps/solver/app.h @@ -29,6 +29,9 @@ public: void tidy() override; EquationStore m_equationStore; }; + static App * app() { + return static_cast(Container::activeApp()); + } InputViewController * inputViewController() { return &m_inputViewController; } ViewController * solutionsControllerStack() { return &m_alternateEmptyViewController; } ViewController * intervalController() { return &m_intervalController; } @@ -45,10 +48,6 @@ private: InputViewController m_inputViewController; }; -inline App * app() { - return static_cast(Container::activeApp()); -} - } #endif diff --git a/apps/solver/interval_controller.cpp b/apps/solver/interval_controller.cpp index 8be37e5a8..c3c5cfaca 100644 --- a/apps/solver/interval_controller.cpp +++ b/apps/solver/interval_controller.cpp @@ -104,7 +104,7 @@ bool IntervalController::textFieldDidFinishEditing(TextField * textField, const void IntervalController::buttonAction() { StackViewController * stack = stackController(); m_equationStore->approximateSolve(textFieldDelegateApp()->localContext()); - stack->push(app()->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); + stack->push(App::app()->solutionsControllerStack(), KDColorWhite, Palette::SubTab, Palette::SubTab); } } diff --git a/apps/solver/list_controller.cpp b/apps/solver/list_controller.cpp index 4efaf10ae..902c226c5 100644 --- a/apps/solver/list_controller.cpp +++ b/apps/solver/list_controller.cpp @@ -192,14 +192,14 @@ void ListController::resolveEquations() { case EquationStore::Error::RequireApproximateSolution: { StackViewController * stack = stackController(); - stack->push(app()->intervalController(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(App::app()->intervalController(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); return; } default: { assert(e == EquationStore::Error::NoError); StackViewController * stack = stackController(); - stack->push(app()->solutionsControllerStack(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); + stack->push(App::app()->solutionsControllerStack(), KDColorWhite, Palette::PurpleBright, Palette::PurpleBright); } } } @@ -233,7 +233,7 @@ StackViewController * ListController::stackController() const { } InputViewController * ListController::inputController() { - return app()->inputViewController(); + return App::app()->inputViewController(); } } diff --git a/apps/solver/solutions_controller.cpp b/apps/solver/solutions_controller.cpp index 6429f3c6d..64fa77f52 100644 --- a/apps/solver/solutions_controller.cpp +++ b/apps/solver/solutions_controller.cpp @@ -108,7 +108,7 @@ void SolutionsController::viewWillAppear() { bool requireWarning = false; if (m_equationStore->type() == EquationStore::Type::Monovariable) { m_contentView.setWarningMessages(I18n::Message::OnlyFirstSolutionsDisplayed0, I18n::Message::OnlyFirstSolutionsDisplayed1); - requireWarning = m_equationStore->haveMoreApproximationSolutions(app()->localContext()); + requireWarning = m_equationStore->haveMoreApproximationSolutions(App::app()->localContext()); } else if (m_equationStore->type() == EquationStore::Type::PolynomialMonovariable && m_equationStore->numberOfSolutions() == 1) { assert(Preferences::sharedPreferences()->complexFormat() == Preferences::ComplexFormat::Real); m_contentView.setWarningMessages(I18n::Message::PolynomeHasNoRealSolution0, I18n::Message::PolynomeHasNoRealSolution1); From bc8b5af2e6136b9074b7b44585ba50b7ef4b2545 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 14:23:15 +0200 Subject: [PATCH 083/111] [escher/modal_view_controller] didBecomeFirstResponder selects modal view if displayed --- escher/src/modal_view_controller.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/escher/src/modal_view_controller.cpp b/escher/src/modal_view_controller.cpp index bbba5cceb..699d75436 100644 --- a/escher/src/modal_view_controller.cpp +++ b/escher/src/modal_view_controller.cpp @@ -136,7 +136,9 @@ void ModalViewController::dismissModalViewController() { } void ModalViewController::didBecomeFirstResponder() { - Container::activeApp()->setFirstResponder(m_regularViewController); + Container::activeApp()->setFirstResponder( + isDisplayingModal() ? m_currentModalViewController : m_regularViewController + ); } bool ModalViewController::handleEvent(Ion::Events::Event event) { From 040a5cfb15dd210015259f362ac8d86eb337b5b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 24 Jul 2019 14:42:22 +0200 Subject: [PATCH 084/111] [apps/regression] Fix typo in the logistic regression formula --- apps/regression/base.universal.i18n | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/regression/base.universal.i18n b/apps/regression/base.universal.i18n index 387275113..bb896dc36 100644 --- a/apps/regression/base.universal.i18n +++ b/apps/regression/base.universal.i18n @@ -5,5 +5,5 @@ LogarithmicRegressionFormula = " y=a·ln(x)+b " ExponentialRegressionFormula = " y=a·exp(b·x) " PowerRegressionFormula = " y=a·x^b " TrigonometricRegressionFormula = " y=a·sin(b·x+c)+d " -LogisticRegressionFormula = " y=c/(a+exp(-b·x)) " +LogisticRegressionFormula = " y=c/(1+a·exp(-b·x)) " Dash = "-" From 7b84b655025df6f9bf7a43cce13bd1252e7fc9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 26 Jul 2019 10:24:19 +0200 Subject: [PATCH 085/111] [apps/code] Fix sandbox and input clash The command "squares()%input()" followed by text, OK, and a backspace event broke an assertion on the consoleStore number of lines. --- apps/code/console_controller.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/code/console_controller.cpp b/apps/code/console_controller.cpp index 1ee21b9cb..12e2a9513 100644 --- a/apps/code/console_controller.cpp +++ b/apps/code/console_controller.cpp @@ -93,6 +93,11 @@ const char * ConsoleController::inputText(const char * prompt) { AppsContainer * appsContainer = AppsContainer::sharedAppsContainer(); m_inputRunLoopActive = true; + // Hide the sandbox if it is displayed + if (sandboxIsDisplayed()) { + hideSandbox(); + } + const char * promptText = prompt; char * s = const_cast(prompt); From 7a4ee746b2a49a090cf920cfe53935ccdea7d607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 30 Jul 2019 11:27:42 +0200 Subject: [PATCH 086/111] [escher] TextField: call reinitDraftBuffer after edition is complete to avoid erasing text that is required later. Fix bug: OK handling on function list in linear mode did not copy the function expression into the textfield before editing --- apps/code/console_edit_cell.cpp | 4 +- apps/code/console_edit_cell.h | 2 +- apps/code/menu_controller.cpp | 4 +- apps/graph/list/list_controller.cpp | 4 +- .../list/text_field_function_title_cell.cpp | 2 +- .../buffer_text_view_with_text_field.cpp | 2 +- escher/include/escher/editable_field.h | 2 +- escher/include/escher/layout_field.h | 2 +- escher/include/escher/text_field.h | 5 +- escher/src/expression_field.cpp | 6 ++- escher/src/text_field.cpp | 50 ++++++++----------- 11 files changed, 40 insertions(+), 43 deletions(-) diff --git a/apps/code/console_edit_cell.cpp b/apps/code/console_edit_cell.cpp index 8e1938aa8..e1c078ca4 100644 --- a/apps/code/console_edit_cell.cpp +++ b/apps/code/console_edit_cell.cpp @@ -38,8 +38,8 @@ void ConsoleEditCell::didBecomeFirstResponder() { Container::activeApp()->setFirstResponder(&m_textField); } -void ConsoleEditCell::setEditing(bool isEditing, bool reinitDraftBuffer) { - m_textField.setEditing(isEditing, reinitDraftBuffer); +void ConsoleEditCell::setEditing(bool isEditing) { + m_textField.setEditing(isEditing); } void ConsoleEditCell::setText(const char * text) { diff --git a/apps/code/console_edit_cell.h b/apps/code/console_edit_cell.h index 8a6b2d9b3..f97c2653d 100644 --- a/apps/code/console_edit_cell.h +++ b/apps/code/console_edit_cell.h @@ -27,7 +27,7 @@ public: } // Edit cell - void setEditing(bool isEditing, bool reinitDraftBuffer = false); + void setEditing(bool isEditing); const char * text() const override { return m_textField.text(); } void setText(const char * text); bool insertText(const char * text); diff --git a/apps/code/menu_controller.cpp b/apps/code/menu_controller.cpp index 381d13e23..c9b163e1d 100644 --- a/apps/code/menu_controller.cpp +++ b/apps/code/menu_controller.cpp @@ -49,7 +49,7 @@ void MenuController::willExitResponderChain(Responder * nextFirstResponder) { if (selectedRow >= 0 && selectedRow < m_scriptStore->numberOfScripts() && selectedColumn == 0) { TextField * tf = static_cast(m_selectableTableView.selectedCell())->textField(); if (tf->isEditing()) { - tf->setEditing(false, false); + tf->setEditing(false); privateTextFieldDidAbortEditing(tf, false); } } @@ -126,7 +126,7 @@ void MenuController::renameSelectedScript() { ScriptNameCell * myCell = static_cast(m_selectableTableView.selectedCell()); Container::activeApp()->setFirstResponder(myCell); myCell->setHighlighted(false); - myCell->textField()->setEditing(true, false); + myCell->textField()->setEditing(true); myCell->textField()->setCursorLocation(myCell->textField()->text() + strlen(myCell->textField()->text())); } diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index ed17fd5d5..9174738a5 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -73,7 +73,7 @@ bool ListController::textFieldDidFinishEditing(TextField * textField, const char // Handle any error if (error == Ion::Storage::Record::ErrorStatus::None) { bool selectTab = false; - textField->setEditing(false, false); + textField->setEditing(false); computeTitlesColumnWidth(); int currentRow = m_selectableTableView.selectedRow(); if (event == Ion::Events::Down && currentRow < numberOfRows() - 1) { @@ -109,7 +109,7 @@ bool ListController::textFieldDidFinishEditing(TextField * textField, const char assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable); Container::activeApp()->displayWarning(I18n::Message::NameTooLong); } - textField->setEditing(true, false); + textField->setEditing(true); return false; } diff --git a/apps/graph/list/text_field_function_title_cell.cpp b/apps/graph/list/text_field_function_title_cell.cpp index 16ef037c3..4953d4621 100644 --- a/apps/graph/list/text_field_function_title_cell.cpp +++ b/apps/graph/list/text_field_function_title_cell.cpp @@ -26,7 +26,7 @@ Responder * TextFieldFunctionTitleCell::responder() { void TextFieldFunctionTitleCell::setEditing(bool editing) { Container::activeApp()->setFirstResponder(&m_textField); const char * previousText = m_textField.text(); - m_textField.setEditing(true, false); + m_textField.setEditing(true); m_textField.setText(previousText); } diff --git a/apps/shared/buffer_text_view_with_text_field.cpp b/apps/shared/buffer_text_view_with_text_field.cpp index ca71591a1..15b149913 100644 --- a/apps/shared/buffer_text_view_with_text_field.cpp +++ b/apps/shared/buffer_text_view_with_text_field.cpp @@ -41,7 +41,7 @@ void BufferTextViewWithTextField::drawRect(KDContext * ctx, KDRect rect) const { void BufferTextViewWithTextField::didBecomeFirstResponder() { Container::activeApp()->setFirstResponder(&m_textField); - m_textField.setEditing(true, false); + m_textField.setEditing(true); markRectAsDirty(bounds()); } diff --git a/escher/include/escher/editable_field.h b/escher/include/escher/editable_field.h index 3e7beeb98..bdee14acc 100644 --- a/escher/include/escher/editable_field.h +++ b/escher/include/escher/editable_field.h @@ -9,7 +9,7 @@ class EditableField : public InputEventHandler { public: using InputEventHandler::InputEventHandler; virtual bool isEditing() const = 0; - virtual void setEditing(bool isEditing, bool reinitDraftBuffer = true) = 0; + virtual void setEditing(bool isEditing) = 0; virtual CodePoint XNTCodePoint(CodePoint defaultXNTCodePoint) = 0; virtual bool shouldFinishEditing(Ion::Events::Event event) = 0; }; diff --git a/escher/include/escher/layout_field.h b/escher/include/escher/layout_field.h index 3994e89d4..ef19f271a 100644 --- a/escher/include/escher/layout_field.h +++ b/escher/include/escher/layout_field.h @@ -21,7 +21,7 @@ public: {} void setDelegates(InputEventHandlerDelegate * inputEventHandlerDelegate, LayoutFieldDelegate * delegate) { m_inputEventHandlerDelegate = inputEventHandlerDelegate; m_delegate = delegate; } bool isEditing() const override { return m_contentView.isEditing(); } - void setEditing(bool isEditing, bool reinitDraftBuffer = false) override { m_contentView.setEditing(isEditing); } + void setEditing(bool isEditing) override { m_contentView.setEditing(isEditing); } void clearLayout() { m_contentView.clearLayout(); } void scrollToCursor() { scrollToBaselinedRect(m_contentView.cursorRect(), m_contentView.cursor()->baseline()); diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index f1e7d1392..b78cd3ce5 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -14,13 +14,14 @@ public: void setBackgroundColor(KDColor backgroundColor) override; void setTextColor(KDColor textColor); void setDelegates(InputEventHandlerDelegate * inputEventHandlerDelegate, TextFieldDelegate * delegate) { m_inputEventHandlerDelegate = inputEventHandlerDelegate; m_delegate = delegate; } + void reinitDraftTextBuffer() { m_contentView.reinitDraftTextBuffer(); } void setDraftTextBuffer(char * draftTextBuffer); bool isEditing() const override; const char * draftTextBuffer() const { return const_cast(this)->m_contentView.draftTextBuffer(); } size_t draftTextLength() const; //TODO keep ? void setText(const char * text); void setAlignment(float horizontalAlignment, float verticalAlignment); - virtual void setEditing(bool isEditing, bool reinitDraftBuffer = true) override; + void setEditing(bool isEditing) override { m_contentView.setEditing(isEditing); } CodePoint XNTCodePoint(CodePoint defaultXNTCodePoint) override; bool handleEventWithText(const char * text, bool indentation = false, bool forceCursorRightOfText = false) override; bool handleEvent(Ion::Events::Event event) override; @@ -48,7 +49,7 @@ protected: int bufferSize() { return k_maxBufferSize; } void setText(const char * text); void setAlignment(float horizontalAlignment, float verticalAlignment); - void setEditing(bool isEditing, bool reinitDraftBuffer); + void setEditing(bool isEditing); void reinitDraftTextBuffer(); /* If the text to be appended is too long to be added without overflowing the * buffer, nothing is done (not even adding few letters from the text to reach diff --git a/escher/src/expression_field.cpp b/escher/src/expression_field.cpp index 043a80de4..649d073d4 100644 --- a/escher/src/expression_field.cpp +++ b/escher/src/expression_field.cpp @@ -23,7 +23,10 @@ ExpressionField::ExpressionField(Responder * parentResponder, char * textBuffer, void ExpressionField::setEditing(bool isEditing, bool reinitDraftBuffer) { if (editionIsInTextField()) { - m_textField.setEditing(isEditing, reinitDraftBuffer); + if (reinitDraftBuffer) { + m_textField.reinitDraftTextBuffer(); + } + m_textField.setEditing(isEditing); } else { if (reinitDraftBuffer) { m_layoutField.clearLayout(); @@ -45,6 +48,7 @@ const char * ExpressionField::text() { void ExpressionField::setText(const char * text) { if (editionIsInTextField()) { + m_textField.reinitDraftTextBuffer(); m_textField.setText(text); } else { m_layoutField.clearLayout(); diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index d85ce90de..13232f5a4 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -22,7 +22,9 @@ TextField::ContentView::ContentView(char * textBuffer, char * draftTextBuffer, s m_backgroundColor(backgroundColor) { assert(m_textBufferSize <= k_maxBufferSize); - m_cursorLocation = draftTextBuffer; + if (m_draftTextBuffer) { + reinitDraftTextBuffer(); + } } void TextField::ContentView::setBackgroundColor(KDColor backgroundColor) { @@ -70,14 +72,11 @@ void TextField::ContentView::setAlignment(float horizontalAlignment, float verti markRectAsDirty(bounds()); } -void TextField::ContentView::setEditing(bool isEditing, bool reinitDrafBuffer) { - if (m_isEditing == isEditing && !reinitDrafBuffer) { +void TextField::ContentView::setEditing(bool isEditing) { + if (m_isEditing == isEditing) { return; } m_isEditing = isEditing; - if (reinitDrafBuffer) { - reinitDraftTextBuffer(); - } m_currentDraftTextLength = strlen(m_draftTextBuffer); if (m_cursorLocation < m_draftTextBuffer || m_cursorLocation > m_draftTextBuffer + m_currentDraftTextLength) @@ -245,6 +244,7 @@ void TextField::setTextColor(KDColor textColor) { void TextField::setDraftTextBuffer(char * draftTextBuffer) { m_contentView.setDraftTextBuffer(draftTextBuffer); + reinitDraftTextBuffer(); } bool TextField::isEditing() const { @@ -268,13 +268,6 @@ void TextField::setAlignment(float horizontalAlignment, float verticalAlignment) m_contentView.setAlignment(horizontalAlignment, verticalAlignment); } -void TextField::setEditing(bool isEditing, bool reinitDrafBuffer) { - m_contentView.setEditing(isEditing, reinitDrafBuffer); - if (reinitDrafBuffer) { - reloadScroll(); - } -} - bool TextField::privateHandleEvent(Ion::Events::Event event) { // Handle Toolbox or Var event if (handleBoxEvent(event)) { @@ -284,10 +277,7 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { return true; } if (isEditing() && shouldFinishEditing(event)) { - char bufferText[ContentView::k_maxBufferSize]; - const char * cursorLoc = cursorLocation(); if (m_hasTwoBuffers) { - strlcpy(bufferText, m_contentView.textBuffer(), ContentView::k_maxBufferSize); strlcpy(m_contentView.textBuffer(), m_contentView.draftTextBuffer(), m_contentView.bufferSize()); } /* If textFieldDidFinishEditing displays a pop-up (because of an unvalid @@ -296,21 +286,18 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { * which we do not want, as we are not really aborting edition, just * displaying a pop-up before returning to edition. * We thus set editing to false. */ - setEditing(false, m_hasTwoBuffers); + setEditing(false); if (m_delegate->textFieldDidFinishEditing(this, text(), event)) { + // Clean draft text for next use + if (m_hasTwoBuffers) { + reinitDraftTextBuffer(); + } /* We allow overscroll to avoid calling layoutSubviews twice because the * content might have changed. */ reloadScroll(true); return true; } - setEditing(true, false); - if (m_hasTwoBuffers) { - /* If the text was refused (textInputDidFinishEditing returned false, we - * reset the textfield in the same state as before */ - setText(m_contentView.textBuffer()); - strlcpy(m_contentView.textBuffer(), bufferText, ContentView::k_maxBufferSize); - setCursorLocation(cursorLoc); - } + setEditing(true); return true; } /* If a move event was not caught before, we handle it here to avoid bubbling @@ -327,7 +314,8 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { return removePreviousGlyph(); } if (event == Ion::Events::Back && isEditing()) { - setEditing(false, m_hasTwoBuffers); + reinitDraftTextBuffer(); + setEditing(false); m_delegate->textFieldDidAbortEditing(this); reloadScroll(true); return true; @@ -344,7 +332,7 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { } if (event == Ion::Events::Cut && !isEditing()) { Clipboard::sharedClipboard()->store(text()); - setEditing(true, true); + setEditing(true); return true; } return false; @@ -416,7 +404,9 @@ bool TextField::handleEvent(Ion::Events::Event event) { } else if (event == Ion::Events::Paste) { return handleEventWithText(Clipboard::sharedClipboard()->storedText()); } else if ((event == Ion::Events::OK || event == Ion::Events::EXE) && !isEditing()) { - return handleEventWithText(m_contentView.textBuffer()); + setEditing(true); + setText(m_contentView.textBuffer()); + didHandleEvent = true; } if (!didHandleEvent) { didHandleEvent = privateHandleEvent(event); @@ -489,5 +479,7 @@ bool TextField::handleEventWithText(const char * eventText, bool indentation, bo } void TextField::removeWholeText() { - setEditing(true, true); + reinitDraftTextBuffer(); + setEditing(true); + reloadScroll(); } From c22754fa636d94149e717171fcd5d7ff484f27c9 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 12 Jun 2019 15:32:32 +0200 Subject: [PATCH 087/111] [apps/shared/curve_view] Make curveViewRange() method const --- apps/probability/law_curve_view.cpp | 2 +- apps/sequence/graph/graph_view.cpp | 2 +- apps/shared/curve_view.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/probability/law_curve_view.cpp b/apps/probability/law_curve_view.cpp index f2d34f077..adfb57e5b 100644 --- a/apps/probability/law_curve_view.cpp +++ b/apps/probability/law_curve_view.cpp @@ -48,7 +48,7 @@ float LawCurveView::EvaluateAtAbscissa(float abscissa, void * model, void * cont void LawCurveView::drawStandardNormal(KDContext * ctx, KDRect rect, float colorLowerBound, float colorUpperBound) const { // Save the previous curve view range LawCurveView * constCastedThis = const_cast(this); - CurveViewRange * previousRange = constCastedThis->curveViewRange(); + CurveViewRange * previousRange = curveViewRange(); // Draw a centered reduced normal curve NormalLaw n; diff --git a/apps/sequence/graph/graph_view.cpp b/apps/sequence/graph/graph_view.cpp index 1577b2e1d..c85c531be 100644 --- a/apps/sequence/graph/graph_view.cpp +++ b/apps/sequence/graph/graph_view.cpp @@ -22,7 +22,7 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { float rectXMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); /* We draw a dot at every integer if WindowRange/Resolution < 1. Otherwise, * we draw a dot at every step where step is an integer wider than 1. */ - float windowRange = pixelToFloat(Axis::Horizontal, bounds().width()) - pixelToFloat(Axis::Horizontal, 0); + float windowRange = curveViewRange()->xMax() - curveViewRange()->xMin(); int step = std::ceil(windowRange/resolution()); for (int x = rectXMin; x < rectXMax; x += step) { float y = s->evaluateAtAbscissa((float)x, context()); diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 1d745383c..25bd0ff4f 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -38,7 +38,7 @@ public: void setForceOkDisplay(bool force) { m_forceOkDisplay = force; } float resolution() const; protected: - CurveViewRange * curveViewRange() { return m_curveViewRange; } + CurveViewRange * curveViewRange() const { return m_curveViewRange; } void setCurveViewRange(CurveViewRange * curveViewRange); // Drawing methods virtual float samplingRatio() const; From f4b7967a580deea947958f196faddcda88a46034 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 11 Jul 2019 11:25:21 +0200 Subject: [PATCH 088/111] [apps/shared/curve_view] step in drawHistogram depends on x-range's width instead of the width of the rect that is being drawn. --- apps/shared/curve_view.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 58fe73a65..c2a0cb268 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -551,10 +551,7 @@ void CurveView::drawHistogram(KDContext * ctx, KDRect rect, EvaluateModelWithPar float rectMaxUpperBound = firstBarAbscissa + (rectMaxBinNumber+1)*barWidth + barWidth; float pHighlightLowerBound = floatToPixel(Axis::Horizontal, highlightLowerBound); float pHighlightUpperBound = floatToPixel(Axis::Horizontal, highlightUpperBound); - float step = barWidth; - if ((rectMaxUpperBound-rectMinLowerBound)/step > resolution()) { - step = (rectMaxUpperBound-rectMinLowerBound)/resolution(); - } + float step = std::fmax(barWidth, (curveViewRange()->xMax() - curveViewRange()->xMin())/resolution()); for (float x = rectMinLowerBound; x < rectMaxUpperBound; x += step) { /* When |rectMinLowerBound| >> step, rectMinLowerBound + step = rectMinLowerBound. * In that case, quit the infinite loop. */ From 503995746a6385aa669f4dbfb07ce9460ce59619 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 11 Jul 2019 11:44:21 +0200 Subject: [PATCH 089/111] [apps/shared/function_graph_controller] Clean resolution usage in computeYRange --- apps/shared/function_graph_controller.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 0b1c19a8b..b8fb476cf 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -84,13 +84,14 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( range.max = xMax; return range; } + float step = (xMax - xMin) / curveView()->resolution(); for (int i=0; inumberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); - float res = curveView()->resolution(); /* Scan x-range from the middle to the extrema in order to get balanced * y-range for even functions (y = 1/x). */ - for (int j = -res/2; j <= res/2; j++) { - float x = (xMin+xMax)/2.0+(xMax-xMin)*j/res; + const int balancedBound = std::floor((xMax-xMin)/2/step); + for (int j = -balancedBound; j <= balancedBound ; j++) { + float x = (xMin+xMax)/2 + step * j; float y = f->evaluateAtAbscissa(x, context); if (!std::isnan(y) && !std::isinf(y)) { min = min < y ? min : y; From f5c3cb74e2afbe021d9e28e2589d7f17cb7d235b Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 16 Jul 2019 09:53:55 +0200 Subject: [PATCH 090/111] [apps/shared/curve_view] Fix rounding error in drawSegment --- apps/shared/curve_view.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index c2a0cb268..405d9062c 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -374,14 +374,14 @@ void CurveView::drawSegment(KDContext * ctx, KDRect rect, Axis axis, float coord switch(axis) { case Axis::Horizontal: lineRect = KDRect( - std::round(floatToPixel(Axis::Horizontal, lowerBound)), std::round(floatToPixel(Axis::Vertical, coordinate)), - std::round(floatToPixel(Axis::Horizontal, upperBound) - floatToPixel(Axis::Horizontal, lowerBound)), thickness - ); + std::round(floatToPixel(Axis::Horizontal, lowerBound)), std::round(floatToPixel(Axis::Vertical, coordinate)), + std::round(floatToPixel(Axis::Horizontal, upperBound)) - std::round(floatToPixel(Axis::Horizontal, lowerBound)), thickness + ); break; case Axis::Vertical: lineRect = KDRect( - std::round(floatToPixel(Axis::Horizontal, coordinate)), std::round(floatToPixel(Axis::Vertical, upperBound)), - thickness, std::round(floatToPixel(Axis::Vertical, lowerBound) - floatToPixel(Axis::Vertical, upperBound)) + std::round(floatToPixel(Axis::Horizontal, coordinate)), std::round(floatToPixel(Axis::Vertical, upperBound)), + thickness, std::round(floatToPixel(Axis::Vertical, lowerBound)) - std::round(floatToPixel(Axis::Vertical, upperBound)) ); break; } From 7cbc489052d7e9382aad44db89b310431e1c9139 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 10 Jul 2019 14:24:12 +0200 Subject: [PATCH 091/111] [apps/shared/curve_view] Use drawSegment to color area under curve --- apps/shared/curve_view.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 405d9062c..979f525af 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -12,6 +12,9 @@ namespace Shared { static inline int minInt(int x, int y) { return x < y ? x : y; } +static inline float minFloat(float x, float y) { return x < y ? x : y; } +static inline float maxFloat(float x, float y) { return x > y ? x : y; } + CurveView::CurveView(CurveViewRange * curveViewRange, CurveViewCursor * curveViewCursor, BannerView * bannerView, View * cursorView, View * okView, bool displayBanner) : View(), @@ -505,9 +508,6 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet float rectMin = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); float rectMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); - float pixelColorLowerBound = std::round(floatToPixel(Axis::Horizontal, colorLowerBound)); - float pixelColorUpperBound = std::round(floatToPixel(Axis::Horizontal, colorUpperBound)); - for (float x = rectMin; x < rectMax; x += xStep) { /* When |rectMin| >> xStep, rectMin + xStep = rectMin. In that case, quit * the infinite loop. */ @@ -518,15 +518,11 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet if (std::isnan(y)|| std::isinf(y)) { continue; } + if (colorUnderCurve && colorLowerBound < x && x < colorUpperBound) { + drawSegment(ctx, rect, Axis::Vertical, x, minFloat(0.0f, y), maxFloat(0.0f, y), color, 1); + } float pxf = floatToPixel(Axis::Horizontal, x); float pyf = floatToPixel(Axis::Vertical, y); - if (colorUnderCurve && pxf > pixelColorLowerBound && pxf < pixelColorUpperBound) { - KDRect colorRect((int)pxf, std::round(pyf), 1, std::round(floatToPixel(Axis::Vertical, 0.0f)) - std::round(pyf)); - if (floatToPixel(Axis::Vertical, 0.0f) < std::round(pyf)) { - colorRect = KDRect((int)pxf, std::round(floatToPixel(Axis::Vertical, 0.0f)), 1, std::round(pyf) - std::round(floatToPixel(Axis::Vertical, 0.0f))); - } - ctx->fillRect(colorRect, color); - } stampAtLocation(ctx, rect, pxf, pyf, color); if (x <= rectMin || std::isnan(evaluation(x-xStep, model, context))) { continue; From c80baae1e9c4f0b092bbc57e782628279bd9fe68 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 11 Jul 2019 11:33:30 +0200 Subject: [PATCH 092/111] [apps/*/curve_view] Remove samplingRatio() The resolution() method is useful to get a horizontal step equivalent to the width of a pixel. A higher sampling ratio (or resolution) had been introduced in the following commit. [apps] In curve view, avoid white vertical lines in integral curves due to pixel rounding --- apps/sequence/graph/graph_view.cpp | 4 ---- apps/sequence/graph/graph_view.h | 1 - apps/shared/curve_view.cpp | 6 +----- apps/shared/curve_view.h | 1 - apps/shared/function_graph_controller.cpp | 2 +- 5 files changed, 2 insertions(+), 12 deletions(-) diff --git a/apps/sequence/graph/graph_view.cpp b/apps/sequence/graph/graph_view.cpp index c85c531be..f18644ebb 100644 --- a/apps/sequence/graph/graph_view.cpp +++ b/apps/sequence/graph/graph_view.cpp @@ -42,8 +42,4 @@ void GraphView::drawRect(KDContext * ctx, KDRect rect) const { } } -float GraphView::samplingRatio() const { - return 2.0f; -} - } diff --git a/apps/sequence/graph/graph_view.h b/apps/sequence/graph/graph_view.h index 97d35ea99..6d86fcb07 100644 --- a/apps/sequence/graph/graph_view.h +++ b/apps/sequence/graph/graph_view.h @@ -12,7 +12,6 @@ public: Shared::CurveViewCursor * cursor, Shared::BannerView * bannerView, View * cursorView); void drawRect(KDContext * ctx, KDRect rect) const override; private: - float samplingRatio() const override; SequenceStore * m_sequenceStore; }; diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 979f525af..9ae40ba00 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -88,11 +88,7 @@ void CurveView::setOkView(View * okView) { } float CurveView::resolution() const { - return bounds().width()*samplingRatio(); -} - -float CurveView::samplingRatio() const { - return 1.1f; + return bounds().width(); } void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float step, KDColor boldColor, KDColor lightColor) const { diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 25bd0ff4f..83730cba6 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -41,7 +41,6 @@ protected: CurveViewRange * curveViewRange() const { return m_curveViewRange; } void setCurveViewRange(CurveViewRange * curveViewRange); // Drawing methods - virtual float samplingRatio() const; constexpr static KDCoordinate k_labelMargin = 4; constexpr static KDCoordinate k_okVerticalMargin = 23; constexpr static KDCoordinate k_okHorizontalMargin = 10; diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index b8fb476cf..4429b3ca7 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -84,7 +84,7 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( range.max = xMax; return range; } - float step = (xMax - xMin) / curveView()->resolution(); + float step = (xMax - xMin) / curveView()->resolution() / 2; for (int i=0; inumberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); /* Scan x-range from the middle to the extrema in order to get balanced From 292493ba36ec5da986dd3a94fe8a8ddec7317f87 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 11 Jul 2019 12:22:56 +0200 Subject: [PATCH 093/111] [apps/*curve_view] Substitute resolution by pixelWidth --- apps/sequence/graph/graph_controller.cpp | 7 ++----- apps/sequence/graph/graph_view.cpp | 7 +++---- apps/shared/curve_view.cpp | 10 ++++------ apps/shared/curve_view.h | 2 +- apps/shared/function_graph_controller.cpp | 2 +- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/apps/sequence/graph/graph_controller.cpp b/apps/sequence/graph/graph_controller.cpp index 0aafbb3f8..6056fbab0 100644 --- a/apps/sequence/graph/graph_controller.cpp +++ b/apps/sequence/graph/graph_controller.cpp @@ -86,11 +86,8 @@ bool GraphController::moveCursorHorizontally(int direction) { if (direction < 0 && xCursorPosition <= 0) { return false; } - /* The cursor moves by step of at minimum 1. If the windowRange is to large - * compared to the resolution, the cursor takes bigger round step to cross - * the window in approximatively resolution steps. */ - double step = std::ceil((interactiveCurveViewRange()->xMax()-interactiveCurveViewRange()->xMin())/m_view.resolution()); - step = step < 1.0 ? 1.0 : step; + // The cursor moves by step that is larger than 1 and than a pixel's width. + const int step = std::ceil(m_view.pixelWidth()); double x = direction > 0 ? xCursorPosition + step: xCursorPosition - step; if (x < 0.0) { diff --git a/apps/sequence/graph/graph_view.cpp b/apps/sequence/graph/graph_view.cpp index f18644ebb..6e0971c2e 100644 --- a/apps/sequence/graph/graph_view.cpp +++ b/apps/sequence/graph/graph_view.cpp @@ -14,16 +14,15 @@ GraphView::GraphView(SequenceStore * sequenceStore, InteractiveCurveViewRange * void GraphView::drawRect(KDContext * ctx, KDRect rect) const { FunctionGraphView::drawRect(ctx, rect); + /* A dot is drawn at every step where step is larger than 1 + * and than a pixel's width. */ + const int step = std::ceil(pixelWidth()); for (int i = 0; i < m_sequenceStore->numberOfActiveFunctions(); i++) { Ion::Storage::Record record = m_sequenceStore->activeRecordAtIndex(i); Sequence * s = m_sequenceStore->modelForRecord(record);; float rectXMin = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); rectXMin = rectXMin < 0 ? 0 : rectXMin; float rectXMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); - /* We draw a dot at every integer if WindowRange/Resolution < 1. Otherwise, - * we draw a dot at every step where step is an integer wider than 1. */ - float windowRange = curveViewRange()->xMax() - curveViewRange()->xMin(); - int step = std::ceil(windowRange/resolution()); for (int x = rectXMin; x < rectXMax; x += step) { float y = s->evaluateAtAbscissa((float)x, context()); if (std::isnan(y)) { diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 9ae40ba00..a63b9af55 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -87,8 +87,8 @@ void CurveView::setOkView(View * okView) { layoutSubviews(); } -float CurveView::resolution() const { - return bounds().width(); +const float CurveView::pixelWidth() const { + return (m_curveViewRange->xMax() - m_curveViewRange->xMin()) / m_frame.width(); } void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float step, KDColor boldColor, KDColor lightColor) const { @@ -498,9 +498,7 @@ const uint8_t stampMask[stampSize+1][stampSize+1] = { constexpr static int k_maxNumberOfIterations = 10; void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, KDColor color, bool colorUnderCurve, float colorLowerBound, float colorUpperBound, bool continuously) const { - float xMin = min(Axis::Horizontal); - float xMax = max(Axis::Horizontal); - float xStep = (xMax-xMin)/resolution(); + const float xStep = pixelWidth(); float rectMin = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); float rectMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); @@ -543,7 +541,7 @@ void CurveView::drawHistogram(KDContext * ctx, KDRect rect, EvaluateModelWithPar float rectMaxUpperBound = firstBarAbscissa + (rectMaxBinNumber+1)*barWidth + barWidth; float pHighlightLowerBound = floatToPixel(Axis::Horizontal, highlightLowerBound); float pHighlightUpperBound = floatToPixel(Axis::Horizontal, highlightUpperBound); - float step = std::fmax(barWidth, (curveViewRange()->xMax() - curveViewRange()->xMin())/resolution()); + const float step = std::fmax(barWidth, pixelWidth()); for (float x = rectMinLowerBound; x < rectMaxUpperBound; x += step) { /* When |rectMinLowerBound| >> step, rectMinLowerBound + step = rectMinLowerBound. * In that case, quit the infinite loop. */ diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 83730cba6..632b54cf5 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -36,7 +36,7 @@ public: void setBannerView(View * bannerView); void setOkView(View * okView); void setForceOkDisplay(bool force) { m_forceOkDisplay = force; } - float resolution() const; + const float pixelWidth() const; protected: CurveViewRange * curveViewRange() const { return m_curveViewRange; } void setCurveViewRange(CurveViewRange * curveViewRange); diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index 4429b3ca7..a283df970 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -84,7 +84,7 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( range.max = xMax; return range; } - float step = (xMax - xMin) / curveView()->resolution() / 2; + const float step = curveView()->pixelWidth() / 2; for (int i=0; inumberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i)); /* Scan x-range from the middle to the extrema in order to get balanced From 01d2db1342666c21b2db0456a2c8ae095e6d9eb8 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 10 Jul 2019 14:35:22 +0200 Subject: [PATCH 094/111] [apps/probability/law_curve_view] No need to convert from pixel to float back and forth --- apps/probability/law_curve_view.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/probability/law_curve_view.cpp b/apps/probability/law_curve_view.cpp index adfb57e5b..d4206753b 100644 --- a/apps/probability/law_curve_view.cpp +++ b/apps/probability/law_curve_view.cpp @@ -21,9 +21,7 @@ void LawCurveView::drawRect(KDContext * ctx, KDRect rect) const { drawLabels(ctx, rect, Axis::Horizontal, false, false, false, 0, k_backgroundColor); if (m_law->type() == Law::Type::Normal) { // Special case for the normal law, which has always the same curve - float pixelColorLowerBound = std::round(floatToPixel(Axis::Horizontal, lowerBound)); - float pixelColorUpperBound = std::round(floatToPixel(Axis::Horizontal, upperBound)); - drawStandardNormal(ctx, rect, pixelColorLowerBound, pixelColorUpperBound); + drawStandardNormal(ctx, rect, lowerBound, upperBound); return; } if (m_law->isContinuous()) { @@ -53,7 +51,7 @@ void LawCurveView::drawStandardNormal(KDContext * ctx, KDRect rect, float colorL // Draw a centered reduced normal curve NormalLaw n; constCastedThis->setCurveViewRange(&n); - drawCurve(ctx, rect, EvaluateAtAbscissa, &n, nullptr, Palette::YellowDark, true, pixelToFloat(Axis::Horizontal, colorLowerBound), pixelToFloat(Axis::Horizontal, colorUpperBound), true); + drawCurve(ctx, rect, EvaluateAtAbscissa, &n, nullptr, Palette::YellowDark, true, colorLowerBound, colorUpperBound, true); // Put back the previous curve view range constCastedThis->setCurveViewRange(previousRange); From 985876f115e017dda32de8e89cbcc55eb0d60eea Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 11 Jul 2019 15:44:41 +0200 Subject: [PATCH 095/111] [apps/shared/curve_view] Simplify drawDot --- apps/shared/curve_view.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index a63b9af55..1089ce872 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -410,22 +410,20 @@ const uint8_t oversizeDotMask[oversizeDotDiameter][oversizeDotDiameter] = { }; -KDColor s_dotWorkingBuffer[dotDiameter*dotDiameter]; -KDColor s_oversizeDotWorkingBuffer[oversizeDotDiameter*oversizeDotDiameter]; - void CurveView::drawDot(KDContext * ctx, KDRect rect, float x, float y, KDColor color, bool oversize) const { + const KDCoordinate diameter = oversize ? oversizeDotDiameter : dotDiameter; KDCoordinate px = std::round(floatToPixel(Axis::Horizontal, x)); KDCoordinate py = std::round(floatToPixel(Axis::Vertical, y)); - if ((px + dotDiameter < rect.left() - k_externRectMargin || px - dotDiameter > rect.right() + k_externRectMargin) || - (py + dotDiameter < rect.top() - k_externRectMargin || py - dotDiameter > rect.bottom() + k_externRectMargin)) { + KDRect dotRect(px - diameter/2, py - diameter/2, diameter, diameter); + if (!rect.intersects(dotRect)) { return; } - KDRect dotRect = KDRect(px - dotDiameter/2, py-dotDiameter/2, dotDiameter, dotDiameter); - ctx->blendRectWithMask(dotRect, color, (const uint8_t *)dotMask, s_dotWorkingBuffer); - if (oversize) { - KDRect oversizeDotRect = KDRect(px - oversizeDotDiameter/2, py-oversizeDotDiameter/2, oversizeDotDiameter, oversizeDotDiameter); - ctx->blendRectWithMask(oversizeDotRect, color, (const uint8_t *)oversizeDotMask, s_oversizeDotWorkingBuffer); - } + KDColor workingBuffer[oversizeDotDiameter*oversizeDotDiameter]; + ctx->blendRectWithMask( + dotRect, color, + oversize ? (const uint8_t *)oversizeDotMask : (const uint8_t *)dotMask, + workingBuffer + ); } void CurveView::drawGrid(KDContext * ctx, KDRect rect) const { From ce75a99d931d46cba9b9d04af5273c31b66fc79e Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Mon, 15 Jul 2019 13:51:48 +0200 Subject: [PATCH 096/111] [apps/shared/curve_view] Simplify drawGridLines' for loop bounds --- apps/shared/curve_view.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 1089ce872..52d5f9c01 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -97,19 +97,17 @@ void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float ste * account for conversion errors. */ float otherAxisMin = pixelToFloat(otherAxis, otherAxis == Axis::Horizontal ? rect.left() - 1 : rect.bottom() + 1); float otherAxisMax = pixelToFloat(otherAxis, otherAxis == Axis::Horizontal ? rect.right() + 1 : rect.top() - 1); - float start = step * ((int)(min(otherAxis)/step)); - float boldStart = 2*step * ((int)(min(otherAxis)/(2*step))); + float start = step * ((int)(otherAxisMin/step)); + float boldStart = 2*step * ((int)(otherAxisMin/(2*step))); bool drawBold = std::fabs(start - boldStart) < FLT_EPSILON; - for (float x = start; x < max(otherAxis); x+= step) { + for (float x = start; x <= otherAxisMax; x+= step) { /* When |start| >> step, start + step = start. In that case, quit the * infinite loop. */ if (x == x-step || x == x+step) { return; } - if (otherAxisMin <= x && x <= otherAxisMax) { - drawLine(ctx, rect, axis, x, drawBold ? boldColor : lightColor); - } + drawLine(ctx, rect, axis, x, drawBold ? boldColor : lightColor); drawBold = !drawBold; } } From 702a222dbc6673652841d0331cb34e19f42fe0e8 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Mon, 15 Jul 2019 14:05:55 +0200 Subject: [PATCH 097/111] [apps/shared/curve_view] Simplify drawGridLines' for loop parameter --- apps/shared/curve_view.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 52d5f9c01..b3c8cd72e 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -97,18 +97,10 @@ void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float ste * account for conversion errors. */ float otherAxisMin = pixelToFloat(otherAxis, otherAxis == Axis::Horizontal ? rect.left() - 1 : rect.bottom() + 1); float otherAxisMax = pixelToFloat(otherAxis, otherAxis == Axis::Horizontal ? rect.right() + 1 : rect.top() - 1); - float start = step * ((int)(otherAxisMin/step)); - float boldStart = 2*step * ((int)(otherAxisMin/(2*step))); - bool drawBold = std::fabs(start - boldStart) < FLT_EPSILON; - - for (float x = start; x <= otherAxisMax; x+= step) { - /* When |start| >> step, start + step = start. In that case, quit the - * infinite loop. */ - if (x == x-step || x == x+step) { - return; - } - drawLine(ctx, rect, axis, x, drawBold ? boldColor : lightColor); - drawBold = !drawBold; + const int start = otherAxisMin/step; + const int end = otherAxisMax/step; + for (int i = start; i <= end; i++) { + drawLine(ctx, rect, axis, i * step, i % 2 == 0 ? boldColor : lightColor); } } From 95be59fdc62527451f691d525722fc13eb2864da Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Mon, 15 Jul 2019 16:51:46 +0200 Subject: [PATCH 098/111] [apps/shared/curve_view] Fix label position rounding error --- apps/shared/curve_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index b3c8cd72e..40e14c969 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -269,7 +269,7 @@ void CurveView::drawLabels(KDContext * ctx, KDRect rect, Axis axis, bool shiftOr if (floatingLabels == FloatingPosition::None) { for (int i = minDrawnLabel; i < maxDrawnLabel; i++) { - int labelPosition = minLabelPixelPosition + (((float)i)/((float)numberLabels-1)) * (maxLabelPixelPosition - minLabelPixelPosition); + KDCoordinate labelPosition = std::round(floatToPixel(axis, labelValueAtIndex(axis, i))); KDRect graduation = axis == Axis::Horizontal ? KDRect( labelPosition, @@ -291,7 +291,7 @@ void CurveView::drawLabels(KDContext * ctx, KDRect rect, Axis axis, bool shiftOr // Draw the labels for (int i = minDrawnLabel; i < maxDrawnLabel; i++) { - int labelPosition = minLabelPixelPosition + (((float)i)/((float)numberLabels-1)) * (maxLabelPixelPosition - minLabelPixelPosition); + KDCoordinate labelPosition = std::round(floatToPixel(axis, labelValueAtIndex(axis, i))); char * labelI = label(axis, i); KDSize textSize = k_font->stringSize(labelI); float xPosition = 0.0f; From ab0bfe20398cb1d6e043a11cf2a58185d661c4d7 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 12 Jul 2019 10:52:54 +0200 Subject: [PATCH 099/111] [apps/shared/curve_view] Inline pixelLength --- apps/shared/curve_view.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 40e14c969..50a2266a7 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -564,15 +564,15 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet return; } // No need to draw if both dots are outside visible area - if ((pyf < -stampSize && pvf < -stampSize) || (pyf > pixelLength(Axis::Vertical)+stampSize && pvf > pixelLength(Axis::Vertical)+stampSize)) { + if ((pyf < -stampSize && pvf < -stampSize) || (pyf > m_frame.height()+stampSize && pvf > m_frame.height()+stampSize)) { return; } // If one of the dot is infinite, we cap it with a dot outside area if (std::isinf(pyf)) { - pyf = pyf > 0 ? pixelLength(Axis::Vertical)+stampSize : -stampSize; + pyf = pyf > 0 ? m_frame.height()+stampSize : -stampSize; } if (std::isinf(pvf)) { - pvf = pvf > 0 ? pixelLength(Axis::Vertical)+stampSize : -stampSize; + pvf = pvf > 0 ? m_frame.height()+stampSize : -stampSize; } if (pyf - ((float)circleDiameter)/2.0f < pvf && pvf < pyf + ((float)circleDiameter)/2.0f) { // the dots are already joined @@ -614,7 +614,7 @@ void CurveView::straightJoinDots(KDContext * ctx, KDRect rect, float pxf, float void CurveView::stampAtLocation(KDContext * ctx, KDRect rect, float pxf, float pyf, KDColor color) const { // We avoid drawing when no part of the stamp is visible - if (pyf < -stampSize - FLT_EPSILON || pyf > pixelLength(Axis::Vertical)+stampSize + FLT_EPSILON) { + if (pyf < -stampSize - FLT_EPSILON || pyf > m_frame.height()+stampSize + FLT_EPSILON) { return; } /* When converting floats to KDCoordinate, we need to add -1 if the float is From f8fd654157d05eabb485e4c98f40e3ec3540ed01 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 16 Jul 2019 11:40:28 +0200 Subject: [PATCH 100/111] [liba/stdint] Define int16_t limits --- liba/include/stdint.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/liba/include/stdint.h b/liba/include/stdint.h index f6b17c207..ef904e710 100644 --- a/liba/include/stdint.h +++ b/liba/include/stdint.h @@ -26,6 +26,9 @@ typedef int64_t int_fast64_t; typedef uint8_t uint_least8_t; +#define INT16_MAX 0x7fff +#define INT16_MIN (-INT16_MAX-1) + #define UINT64_C(c) c ## ULL #define INT64_C(c) c ## LL From 07474caf6cb83539453e2bff785988ac226cd209 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 16 Jul 2019 11:41:45 +0200 Subject: [PATCH 101/111] [kandinsky/coordinate] Define KDCoordinate limits --- kandinsky/include/kandinsky/coordinate.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kandinsky/include/kandinsky/coordinate.h b/kandinsky/include/kandinsky/coordinate.h index cb583a0f8..b820abe4d 100644 --- a/kandinsky/include/kandinsky/coordinate.h +++ b/kandinsky/include/kandinsky/coordinate.h @@ -5,4 +5,7 @@ typedef int16_t KDCoordinate; +#define KDCOORDINATE_MAX INT16_MAX +#define KDCOORDINATE_MIN INT16_MIN + #endif From 585b77c38f1caa366819e62ea48155ee54ddb784 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 12 Jul 2019 12:02:22 +0200 Subject: [PATCH 102/111] [apps/shared/curve_view] Clarify coordinates' conventions --- apps/shared/curve_view.cpp | 74 ++++++++++++------- apps/shared/curve_view.h | 2 +- .../interactive_curve_view_controller.cpp | 2 +- ...simple_interactive_curve_view_controller.h | 8 +- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 50a2266a7..37ec62e23 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -87,8 +87,53 @@ void CurveView::setOkView(View * okView) { layoutSubviews(); } +/* We need to locate physical points on the screen more precisely than pixels, + * hence by floating-point coordinates. We agree that the coordinates of the + * center of a pixel corresponding to KDPoint(x,y) are precisely (x,y). In + * particular, the coordinates of a pixel's corners are not integers but half + * integers. Finally, a physical point with floating-point coordinates (x,y) + * is located in the pixel with coordinates (std::round(x), std::round(y)). + * + * Translating CurveViewRange coordinates to pixel coordinates on the screen: + * Along the horizontal axis + * Pixel / physical coordinate CurveViewRange coordinate + * 0 xMin() + * m_frame.width() - 1 xMax() + * Along the vertical axis + * Pixel / physical coordinate CurveViewRange coordinate + * 0 yMax() + * m_frame.height() - 1 yMin() + */ + const float CurveView::pixelWidth() const { - return (m_curveViewRange->xMax() - m_curveViewRange->xMin()) / m_frame.width(); + return (m_curveViewRange->xMax() - m_curveViewRange->xMin()) / (m_frame.width() - 1); +} + +const float CurveView::pixelHeight() const { + return (m_curveViewRange->yMax() - m_curveViewRange->yMin()) / (m_frame.height() - 1); +} + +float CurveView::pixelToFloat(Axis axis, KDCoordinate p) const { + return (axis == Axis::Horizontal) ? + m_curveViewRange->xMin() + p * pixelWidth() : + m_curveViewRange->yMax() - p * pixelHeight(); +} + +float CurveView::floatToPixel(Axis axis, float f) const { + float result = (axis == Axis::Horizontal) ? + (f - m_curveViewRange->xMin()) / pixelWidth() : + (m_curveViewRange->yMax() - f) / pixelHeight(); + /* Make sure that the returned value is between the maximum and minimum + * possible values of KDCoordinate. */ + if (result == NAN) { + return NAN; + } else if (result < KDCOORDINATE_MIN) { + return KDCOORDINATE_MIN; + } else if (result > KDCOORDINATE_MAX) { + return KDCOORDINATE_MAX; + } else { + return result; + } } void CurveView::drawGridLines(KDContext * ctx, KDRect rect, Axis axis, float step, KDColor boldColor, KDColor lightColor) const { @@ -118,11 +163,6 @@ float CurveView::gridUnit(Axis axis) const { return (axis == Axis::Horizontal ? m_curveViewRange->xGridUnit() : m_curveViewRange->yGridUnit()); } -KDCoordinate CurveView::pixelLength(Axis axis) const { - assert(axis == Axis::Horizontal || axis == Axis::Vertical); - return (axis == Axis::Horizontal ? m_frame.width() : m_frame.height()); -} - int CurveView::numberOfLabels(Axis axis) const { float labelStep = 2.0f * gridUnit(axis); float minLabel = std::ceil(min(axis)/labelStep); @@ -130,28 +170,6 @@ int CurveView::numberOfLabels(Axis axis) const { return maxLabel - minLabel + 1; } -float CurveView::pixelToFloat(Axis axis, KDCoordinate p) const { - float pixelLen = pixelLength(axis); - float minA = min(axis); - KDCoordinate pixels = axis == Axis::Horizontal ? p : pixelLen - p; - return minA + pixels*(max(axis)-minA)/pixelLen; -} - -float CurveView::floatToPixel(Axis axis, float f) const { - float fraction = (f-min(axis))/(max(axis)-min(axis)); - fraction = axis == Axis::Horizontal ? fraction : 1.0f - fraction; - /* Fraction is a float that translates the relative position of f on the axis. - * When fraction is between 0 and 1, f is visible. Otherwise, f is out of the - * visible window. We need to clip fraction to avoid big float issue (often - * due to float to int transformation). However, we cannot clip fraction - * between 0 and 1 because drawing a sized stamp on the extern boarder of the - * window should still be visible. We thus arbitrarily clip fraction between - * -10 and 10. */ - fraction = fraction < -10.0f ? -10.0f : fraction; - fraction = fraction > 10.0f ? 10.0f : fraction; - return pixelLength(axis)*fraction; -} - void CurveView::computeLabels(Axis axis) { float step = gridUnit(axis); int axisLabelsCount = numberOfLabels(axis); diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 632b54cf5..347a55b7b 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -37,6 +37,7 @@ public: void setOkView(View * okView); void setForceOkDisplay(bool force) { m_forceOkDisplay = force; } const float pixelWidth() const; + const float pixelHeight() const; protected: CurveViewRange * curveViewRange() const { return m_curveViewRange; } void setCurveViewRange(CurveViewRange * curveViewRange); @@ -78,7 +79,6 @@ private: float min(Axis axis) const; float max(Axis axis) const; float gridUnit(Axis axis) const; - KDCoordinate pixelLength(Axis axis) const; virtual char * label(Axis axis, int index) const = 0; int numberOfLabels(Axis axis) const; /* Recursively join two dots (dichotomy). The method stops when the diff --git a/apps/shared/interactive_curve_view_controller.cpp b/apps/shared/interactive_curve_view_controller.cpp index 74ea2fd6f..547dbd638 100644 --- a/apps/shared/interactive_curve_view_controller.cpp +++ b/apps/shared/interactive_curve_view_controller.cpp @@ -276,7 +276,7 @@ int InteractiveCurveViewController::closestCurveIndexVertically(bool goingUp, in } float InteractiveCurveViewController::cursorBottomMarginRatio() { - return (curveView()->cursorView()->minimalSizeForOptimalDisplay().height()/2+estimatedBannerHeight())/k_viewHeight; + return (curveView()->cursorView()->minimalSizeForOptimalDisplay().height()/2+estimatedBannerHeight())/(k_viewHeight-1); } float InteractiveCurveViewController::estimatedBannerHeight() const { diff --git a/apps/shared/simple_interactive_curve_view_controller.h b/apps/shared/simple_interactive_curve_view_controller.h index 16eb6d627..ab6a40e53 100644 --- a/apps/shared/simple_interactive_curve_view_controller.h +++ b/apps/shared/simple_interactive_curve_view_controller.h @@ -20,10 +20,10 @@ public: bool textFieldDidAbortEditing(TextField * textField) override; bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; protected: - constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth - constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/graphViewWidth - virtual float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2)/graphViewHeight - virtual float cursorBottomMarginRatio() = 0; // (cursorHeight/2+bannerHeight)/graphViewHeight + constexpr static float k_cursorRightMarginRatio = 0.04f; // (cursorWidth/2)/(graphViewWidth-1) + constexpr static float k_cursorLeftMarginRatio = 0.04f; // (cursorWidth/2)/(graphViewWidth-1) + virtual float cursorTopMarginRatio() { return 0.07f; } // (cursorHeight/2)/(graphViewHeight-1) + virtual float cursorBottomMarginRatio() = 0; // (cursorHeight/2+bannerHeight)/(graphViewHeight-1) constexpr static float k_numberOfCursorStepsInGradUnit = 5.0f; virtual bool handleZoom(Ion::Events::Event event); virtual bool handleLeftRightEvent(Ion::Events::Event event); From 9ab55e6a04c58549068e8be0e10d5f953f006a62 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Tue, 18 Jun 2019 17:25:12 +0200 Subject: [PATCH 103/111] [apps/shared/curve_view] drawCurve does not call straightJoinDots anymore Remove the "bool continuously" parameter of the method drawCurve that allowed to bypass the call to jointDots and call straightJoinDots directly instead. --- apps/probability/law_curve_view.cpp | 4 ++-- apps/shared/curve_view.cpp | 10 ++-------- apps/shared/curve_view.h | 2 +- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/apps/probability/law_curve_view.cpp b/apps/probability/law_curve_view.cpp index d4206753b..d336aa9c4 100644 --- a/apps/probability/law_curve_view.cpp +++ b/apps/probability/law_curve_view.cpp @@ -25,7 +25,7 @@ void LawCurveView::drawRect(KDContext * ctx, KDRect rect) const { return; } if (m_law->isContinuous()) { - drawCurve(ctx, rect, EvaluateAtAbscissa, m_law, nullptr, Palette::YellowDark, true, lowerBound, upperBound, true); + drawCurve(ctx, rect, EvaluateAtAbscissa, m_law, nullptr, Palette::YellowDark, true, lowerBound, upperBound); } else { drawHistogram(ctx, rect, EvaluateAtAbscissa, m_law, nullptr, 0, 1, false, Palette::GreyMiddle, Palette::YellowDark, lowerBound, upperBound+0.5f); } @@ -51,7 +51,7 @@ void LawCurveView::drawStandardNormal(KDContext * ctx, KDRect rect, float colorL // Draw a centered reduced normal curve NormalLaw n; constCastedThis->setCurveViewRange(&n); - drawCurve(ctx, rect, EvaluateAtAbscissa, &n, nullptr, Palette::YellowDark, true, colorLowerBound, colorUpperBound, true); + drawCurve(ctx, rect, EvaluateAtAbscissa, &n, nullptr, Palette::YellowDark, true, colorLowerBound, colorUpperBound); // Put back the previous curve view range constCastedThis->setCurveViewRange(previousRange); diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 37ec62e23..05791d223 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -503,7 +503,7 @@ const uint8_t stampMask[stampSize+1][stampSize+1] = { constexpr static int k_maxNumberOfIterations = 10; -void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, KDColor color, bool colorUnderCurve, float colorLowerBound, float colorUpperBound, bool continuously) const { +void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, KDColor color, bool colorUnderCurve, float colorLowerBound, float colorUpperBound) const { const float xStep = pixelWidth(); float rectMin = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); float rectMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); @@ -527,13 +527,7 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet if (x <= rectMin || std::isnan(evaluation(x-xStep, model, context))) { continue; } - if (continuously) { - float puf = floatToPixel(Axis::Horizontal, x - xStep); - float pvf = floatToPixel(Axis::Vertical, evaluation(x-xStep, model, context)); - straightJoinDots(ctx, rect, puf, pvf, pxf, pyf, color); - } else { - jointDots(ctx, rect, evaluation, model, context, x - xStep, evaluation(x-xStep, model, context), x, y, color, k_maxNumberOfIterations); - } + jointDots(ctx, rect, evaluation, model, context, x - xStep, evaluation(x-xStep, model, context), x, y, color, k_maxNumberOfIterations); } } diff --git a/apps/shared/curve_view.h b/apps/shared/curve_view.h index 347a55b7b..a3742db1d 100644 --- a/apps/shared/curve_view.h +++ b/apps/shared/curve_view.h @@ -63,7 +63,7 @@ protected: void drawGrid(KDContext * ctx, KDRect rect) const; void drawAxes(KDContext * ctx, KDRect rect) const; void drawAxis(KDContext * ctx, KDRect rect, Axis axis) const; - void drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, KDColor color, bool colorUnderCurve = false, float colorLowerBound = 0.0f, float colorUpperBound = 0.0f, bool continuously = false) const; + void drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, KDColor color, bool colorUnderCurve = false, float colorLowerBound = 0.0f, float colorUpperBound = 0.0f) const; void drawHistogram(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, float firstBarAbscissa, float barWidth, bool fillBar, KDColor defaultColor, KDColor highlightColor, float highlightLowerBound = INFINITY, float highlightUpperBound = -INFINITY) const; void computeLabels(Axis axis); From 327547dd37b0ce0d0607996ed5e14160021483b3 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 19 Jun 2019 12:08:00 +0200 Subject: [PATCH 104/111] [apps/shared/curve_view] Do not evaluate several times in drawCurve --- apps/shared/curve_view.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 05791d223..3a3b6c408 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -508,13 +508,16 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet float rectMin = pixelToFloat(Axis::Horizontal, rect.left() - k_externRectMargin); float rectMax = pixelToFloat(Axis::Horizontal, rect.right() + k_externRectMargin); + float previousY = NAN; + float y = NAN; for (float x = rectMin; x < rectMax; x += xStep) { /* When |rectMin| >> xStep, rectMin + xStep = rectMin. In that case, quit * the infinite loop. */ if (x == x-xStep || x == x+xStep) { return; } - float y = evaluation(x, model, context); + previousY = y; + y = evaluation(x, model, context); if (std::isnan(y)|| std::isinf(y)) { continue; } @@ -524,10 +527,10 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet float pxf = floatToPixel(Axis::Horizontal, x); float pyf = floatToPixel(Axis::Vertical, y); stampAtLocation(ctx, rect, pxf, pyf, color); - if (x <= rectMin || std::isnan(evaluation(x-xStep, model, context))) { + if (std::isnan(previousY)) { continue; } - jointDots(ctx, rect, evaluation, model, context, x - xStep, evaluation(x-xStep, model, context), x, y, color, k_maxNumberOfIterations); + jointDots(ctx, rect, evaluation, model, context, x - xStep, previousY, x, y, color, k_maxNumberOfIterations); } } From b4099180a390bed2c4313246cbad2790b18f7310 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 10 Jul 2019 15:25:16 +0200 Subject: [PATCH 105/111] [apps/shared/curve_view] Correctly check whether successive dots are joined --- apps/shared/curve_view.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 3a3b6c408..b88bdf164 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -573,11 +573,19 @@ void CurveView::drawHistogram(KDContext * ctx, KDRect rect, EvaluateModelWithPar } void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParameter evaluation, void * model, void * context, float x, float y, float u, float v, KDColor color, int maxNumberOfRecursion) const { + float pxf = floatToPixel(Axis::Horizontal, x); float pyf = floatToPixel(Axis::Vertical, y); + float puf = floatToPixel(Axis::Horizontal, u); float pvf = floatToPixel(Axis::Vertical, v); if (std::isnan(pyf) || std::isnan(pvf)) { return; } + const float deltaX = pxf - puf; + const float deltaY = pyf - pvf; + if (deltaX*deltaX + deltaY*deltaY < circleDiameter * circleDiameter / 4.0f) { + // the dots are already joined + return; + } // No need to draw if both dots are outside visible area if ((pyf < -stampSize && pvf < -stampSize) || (pyf > m_frame.height()+stampSize && pvf > m_frame.height()+stampSize)) { return; @@ -589,21 +597,12 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet if (std::isinf(pvf)) { pvf = pvf > 0 ? m_frame.height()+stampSize : -stampSize; } - if (pyf - ((float)circleDiameter)/2.0f < pvf && pvf < pyf + ((float)circleDiameter)/2.0f) { - // the dots are already joined - return; - } // C is the dot whose abscissa is between x and u float cx = (x + u)/2.0f; float cy = evaluation(cx, model, context); if ((y <= cy && cy <= v) || (v <= cy && cy <= y)) { /* As the middle dot is vertically between the two dots, we assume that we * can draw a 'straight' line between the two */ - float pxf = floatToPixel(Axis::Horizontal, x); - float puf = floatToPixel(Axis::Horizontal, u); - if (std::isnan(pxf) || std::isnan(puf)) { - return; - } straightJoinDots(ctx, rect, pxf, pyf, puf, pvf, color); return; } From 0d82e40b1c48e0d330116b3f4197cad0a9105984 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Thu, 20 Jun 2019 16:22:29 +0200 Subject: [PATCH 106/111] [apps/shared/curve_view] Clean straightJoinDots --- apps/shared/curve_view.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index b88bdf164..7278099d8 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -616,14 +616,17 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet } void CurveView::straightJoinDots(KDContext * ctx, KDRect rect, float pxf, float pyf, float puf, float pvf, KDColor color) const { - if (pyf <= pvf) { - for (float pnf = pyf; pnf Date: Fri, 12 Jul 2019 15:41:05 +0200 Subject: [PATCH 107/111] [apps/shared/curve_view] Gather NAN detections in jointDots --- apps/shared/curve_view.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 7278099d8..abe30160a 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -527,9 +527,6 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet float pxf = floatToPixel(Axis::Horizontal, x); float pyf = floatToPixel(Axis::Vertical, y); stampAtLocation(ctx, rect, pxf, pyf, color); - if (std::isnan(previousY)) { - continue; - } jointDots(ctx, rect, evaluation, model, context, x - xStep, previousY, x, y, color, k_maxNumberOfIterations); } } @@ -577,12 +574,9 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet float pyf = floatToPixel(Axis::Vertical, y); float puf = floatToPixel(Axis::Horizontal, u); float pvf = floatToPixel(Axis::Vertical, v); - if (std::isnan(pyf) || std::isnan(pvf)) { - return; - } const float deltaX = pxf - puf; const float deltaY = pyf - pvf; - if (deltaX*deltaX + deltaY*deltaY < circleDiameter * circleDiameter / 4.0f) { + if (std::isnan(y) || deltaX*deltaX + deltaY*deltaY < circleDiameter * circleDiameter / 4.0f) { // the dots are already joined return; } From 75a273be2a77c24c9239a6354f212e05ea4867ec Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 12 Jul 2019 15:47:02 +0200 Subject: [PATCH 108/111] [apps/shared/curve_view] Gather calls to stampAtLocation in jointDots --- apps/shared/curve_view.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index abe30160a..8402e4676 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -524,9 +524,6 @@ void CurveView::drawCurve(KDContext * ctx, KDRect rect, EvaluateModelWithParamet if (colorUnderCurve && colorLowerBound < x && x < colorUpperBound) { drawSegment(ctx, rect, Axis::Vertical, x, minFloat(0.0f, y), maxFloat(0.0f, y), color, 1); } - float pxf = floatToPixel(Axis::Horizontal, x); - float pyf = floatToPixel(Axis::Vertical, y); - stampAtLocation(ctx, rect, pxf, pyf, color); jointDots(ctx, rect, evaluation, model, context, x - xStep, previousY, x, y, color, k_maxNumberOfIterations); } } @@ -578,6 +575,7 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet const float deltaY = pyf - pvf; if (std::isnan(y) || deltaX*deltaX + deltaY*deltaY < circleDiameter * circleDiameter / 4.0f) { // the dots are already joined + stampAtLocation(ctx, rect, puf, pvf, color); return; } // No need to draw if both dots are outside visible area @@ -600,10 +598,7 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet straightJoinDots(ctx, rect, pxf, pyf, puf, pvf, color); return; } - float pcxf = floatToPixel(Axis::Horizontal, cx); - float pcyf = floatToPixel(Axis::Vertical, cy); if (maxNumberOfRecursion > 0) { - stampAtLocation(ctx, rect, pcxf, pcyf, color); jointDots(ctx, rect, evaluation, model, context, x, y, cx, cy, color, maxNumberOfRecursion-1); jointDots(ctx, rect, evaluation, model, context, cx, cy, u, v, color, maxNumberOfRecursion-1); } From 79dbdaa98ce30cdd6401a53915df1d40f6781947 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 21 Jun 2019 14:18:39 +0200 Subject: [PATCH 109/111] [apps/shared/curve_view] stampAtLocation: clarify stampRect and shiftedMask --- apps/shared/curve_view.cpp | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 8402e4676..0e06e3a27 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -619,31 +619,37 @@ void CurveView::straightJoinDots(KDContext * ctx, KDRect rect, float pxf, float } void CurveView::stampAtLocation(KDContext * ctx, KDRect rect, float pxf, float pyf, KDColor color) const { - // We avoid drawing when no part of the stamp is visible - if (pyf < -stampSize - FLT_EPSILON || pyf > m_frame.height()+stampSize + FLT_EPSILON) { - return; - } - /* When converting floats to KDCoordinate, we need to add -1 if the float is - * negative, otherwise all floats in ]-1.0;1.0[ are converted to 0 and there - * is a blob for x = 0. Try for instance f(x)=cos(x), the blob is at the - * intersection of the curve with the left of the screen. */ - KDCoordinate px = pxf + (pxf >= 0 ? 0 : -1); - KDCoordinate py = pyf + (pyf >= 0 ? 0 : -1); - KDRect stampRect(px-(circleDiameter-2)/2, py-(circleDiameter-2)/2, stampSize, stampSize); + /* The (pxf, pyf) coordinates are not generally locating the center of a + * pixel. We use stampMask, which is one pixel wider and higher than + * stampSize, in order to cover stampRect without aligning the pixels. Then + * shiftedMask is computed so that each pixel is the average of the values of + * the four pixels of stampMask by which it is covered, proportionally to the + * area of the intersection with each of those. + * + * In order to compute the coordinates (px, py) of the top-left pixel of + * stampRect, we consider that stampMask is centered at the provided point + * (pxf,pyf) which is then translated to the center of the top-left pixel of + * stampMask. + */ + pxf -= (stampSize + 1 - 1)/2.0f; + pyf -= (stampSize + 1 - 1)/2.0f; + const KDCoordinate px = std::ceil(pxf); + const KDCoordinate py = std::ceil(pyf); + KDRect stampRect(px, py, stampSize, stampSize); if (!rect.intersects(stampRect)) { return; } uint8_t shiftedMask[stampSize][stampSize]; KDColor workingBuffer[stampSize*stampSize]; - float dx = pxf - std::floor(pxf); - float dy = pyf - std::floor(pyf); + const float dx = px - pxf; + const float dy = py - pyf; /* TODO: this could be optimized by precomputing 10 or 100 shifted masks. The * dx and dy would be rounded to one tenth or one hundredth to choose the * right shifted mask. */ for (int i=0; iblendRectWithMask(stampRect, color, (const uint8_t *)shiftedMask, workingBuffer); From bc750ef2da72cfff6f4cacd5bb24353d18046e8b Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Wed, 10 Jul 2019 16:05:23 +0200 Subject: [PATCH 110/111] [apps/shared/curve_view] Clean clipping of the line segment for straightJoinDots --- apps/shared/curve_view.cpp | 50 +++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/apps/shared/curve_view.cpp b/apps/shared/curve_view.cpp index 0e06e3a27..57d90bad6 100644 --- a/apps/shared/curve_view.cpp +++ b/apps/shared/curve_view.cpp @@ -578,17 +578,6 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet stampAtLocation(ctx, rect, puf, pvf, color); return; } - // No need to draw if both dots are outside visible area - if ((pyf < -stampSize && pvf < -stampSize) || (pyf > m_frame.height()+stampSize && pvf > m_frame.height()+stampSize)) { - return; - } - // If one of the dot is infinite, we cap it with a dot outside area - if (std::isinf(pyf)) { - pyf = pyf > 0 ? m_frame.height()+stampSize : -stampSize; - } - if (std::isinf(pvf)) { - pvf = pvf > 0 ? m_frame.height()+stampSize : -stampSize; - } // C is the dot whose abscissa is between x and u float cx = (x + u)/2.0f; float cy = evaluation(cx, model, context); @@ -604,7 +593,46 @@ void CurveView::jointDots(KDContext * ctx, KDRect rect, EvaluateModelWithParamet } } +static void clipBarycentricCoordinatesBetweenBounds(float & start, float & end, const KDCoordinate * bounds, const float p1f, const float p2f) { + static constexpr int lower = 0; + static constexpr int upper = 1; + if (p1f == p2f) { + if (p1f < bounds[lower] || bounds[upper] < p1f) { + start = 1; + end = 0; + } + } else { + start = maxFloat(start, (bounds[(p1f > p2f) ? lower : upper] - p2f)/(p1f-p2f)); + end = minFloat( end , (bounds[(p1f > p2f) ? upper : lower] - p2f)/(p1f-p2f)); + } +} + void CurveView::straightJoinDots(KDContext * ctx, KDRect rect, float pxf, float pyf, float puf, float pvf, KDColor color) const { + { + /* Before drawing the line segment, clip it to rect: + * start and end are the barycentric coordinates on the line segment (0 + * corresponding to (u, v) and 1 to (x, y)), of the drawing start and end + * points. */ + float start = 0; + float end = 1; + const KDCoordinate xBounds[2] = { + static_cast(rect.left() - stampSize), + static_cast(rect.right() + stampSize) + }; + const KDCoordinate yBounds[2] = { + static_cast(rect.top() - stampSize), + static_cast(rect.bottom() + stampSize) + }; + clipBarycentricCoordinatesBetweenBounds(start, end, xBounds, pxf, puf); + clipBarycentricCoordinatesBetweenBounds(start, end, yBounds, pyf, pvf); + if (start > end) { + return; + } + puf = start * pxf + (1-start) * puf; + pvf = start * pyf + (1-start) * pvf; + pxf = end * pxf + (1- end ) * puf; + pyf = end * pyf + (1- end ) * pvf; + } const float deltaX = pxf - puf; const float deltaY = pyf - pvf; const float normsRatio = std::sqrt(deltaX*deltaX + deltaY*deltaY) / (circleDiameter / 2.0f); From d171c2a2be44b7784612c7cede04df85c3504c49 Mon Sep 17 00:00:00 2001 From: Ruben Dashyan Date: Fri, 19 Jul 2019 14:51:52 +0200 Subject: [PATCH 111/111] [apps/shared/function_graph_controller] Comment about the sampling step in computeYRange --- apps/shared/function_graph_controller.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/shared/function_graph_controller.cpp b/apps/shared/function_graph_controller.cpp index a283df970..14bd3473e 100644 --- a/apps/shared/function_graph_controller.cpp +++ b/apps/shared/function_graph_controller.cpp @@ -84,6 +84,9 @@ InteractiveCurveViewRangeDelegate::Range FunctionGraphController::computeYRange( range.max = xMax; return range; } + /* In practice, a step smaller than a pixel's width is needed for sampling + * the values of a function. Otherwise some relevant extremal values may be + * missed. */ const float step = curveView()->pixelWidth() / 2; for (int i=0; inumberOfActiveFunctions(); i++) { ExpiringPointer f = functionStore()->modelForRecord(functionStore()->activeRecordAtIndex(i));