diff --git a/apps/apps_container.cpp b/apps/apps_container.cpp index 0a2143a35..52c6a45a6 100644 --- a/apps/apps_container.cpp +++ b/apps/apps_container.cpp @@ -57,7 +57,7 @@ AppsContainer::AppsContainer() : m_window(), m_emptyBatteryWindow(), m_globalContext(), - m_variableBoxController(&m_globalContext), + m_variableBoxController(), m_examPopUpController(this), #if EPSILON_BOOT_PROMPT == EPSILON_BETA_PROMPT m_promptController(sPromptMessages, sPromptColors, 8), diff --git a/apps/variable_box_controller.cpp b/apps/variable_box_controller.cpp index 2f4758032..7f1e3dc0c 100644 --- a/apps/variable_box_controller.cpp +++ b/apps/variable_box_controller.cpp @@ -4,124 +4,48 @@ #include #include #include +#include using namespace Poincare; using namespace Shared; +using namespace Ion; -/* ContentViewController */ - -VariableBoxController::ContentViewController::ContentViewController(Responder * parentResponder, GlobalContext * context) : - ViewController(parentResponder), - m_context(context), - m_sender(nullptr), - m_firstSelectedRow(0), - m_previousSelectedRow(0), - m_currentPage(Page::RootMenu), - m_selectableTableView(this) +VariableBoxController::VariableBoxController() : + NestedMenuController(nullptr, I18n::Message::Variables), + m_currentPage(Page::RootMenu) { - m_selectableTableView.setMargins(0); - m_selectableTableView.setShowsIndicators(false); } -View * VariableBoxController::ContentViewController::view() { - return &m_selectableTableView; -} - -const char * VariableBoxController::ContentViewController::title() { - return I18n::translate(I18n::Message::Variables); -} -void VariableBoxController::ContentViewController::didBecomeFirstResponder() { +void VariableBoxController::viewWillAppear() { + StackViewController::viewWillAppear(); + m_currentPage = Page::RootMenu; m_selectableTableView.reloadData(); - m_selectableTableView.scrollToCell(0,0); - selectCellAtLocation(0, m_firstSelectedRow); - app()->setFirstResponder(&m_selectableTableView); } -bool VariableBoxController::ContentViewController::handleEvent(Ion::Events::Event event) { -#if MATRIX_VARIABLES - if (event == Ion::Events::Back && m_currentPage == Page::RootMenu) { -#else - if (event == Ion::Events::Back && m_currentPage == Page::Scalar) { -#endif - m_firstSelectedRow = 0; - app()->dismissModalViewController(); - return true; - } - if (event == Ion::Events::Back || event == Ion::Events::Left) { - m_firstSelectedRow = m_previousSelectedRow; -#if MATRIX_VARIABLES - m_selectableTableView.deselectTable(); - m_currentPage = Page::RootMenu; -#endif - app()->setFirstResponder(this); - return true; - } - if (event == Ion::Events::OK || event == Ion::Events::EXE || (event == Ion::Events::Right && m_currentPage == Page::RootMenu)) { - if (m_currentPage == Page::RootMenu) { - m_previousSelectedRow = selectedRow(); - m_firstSelectedRow = 0; - m_selectableTableView.deselectTable(); - m_currentPage = pageAtIndex(m_previousSelectedRow); - app()->setFirstResponder(this); - return true; - } - m_firstSelectedRow = 0; - char label[3]; - putLabelAtIndexInBuffer(selectedRow(), label); - const char * editedText = label; - m_sender->handleEventWithText(editedText); -#if MATRIX_VARIABLES - m_selectableTableView.deselectTable(); - m_currentPage = Page::RootMenu; -#endif - app()->dismissModalViewController(); - return true; - } +bool VariableBoxController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Backspace && m_currentPage != Page::RootMenu) { - if (m_currentPage == Page::Scalar) { - const char symbolName[2] = {static_cast('A'+selectedRow()), 0}; - Symbol symbol = Symbol(symbolName, 2); - m_context->setExpressionForSymbol(Expression(), symbol, *m_context); - } - if (m_currentPage == Page::Matrix) { - const Symbol symbol("M0", 2); // FIXME: dummy variable box controller - m_context->setExpressionForSymbol(Expression(), symbol, *m_context); - m_matrixLayouts[selectedRow()] = Layout(); - } + Storage::Record record = recordAtIndex(selectedRow()); + record.destroy(); m_selectableTableView.reloadData(); return true; } - return false; + return NestedMenuController::handleEvent(event); } -int VariableBoxController::ContentViewController::numberOfRows() { +int VariableBoxController::numberOfRows() { switch (m_currentPage) { case Page::RootMenu: return k_numberOfMenuRows; - case Page::Scalar: - return 100; // FIXME -#if LIST_VARIABLES - case Page::List: -#endif - case Page::Matrix: - return 100; //FIXME + case Page::Expression: + return Storage::sharedStorage()->numberOfRecordsWithExtension(GlobalContext::expExtension); + case Page::Function: + return Storage::sharedStorage()->numberOfRecordsWithExtension(GlobalContext::funcExtension); default: return 0; } } -HighlightCell * VariableBoxController::ContentViewController::reusableCell(int index, int type) { - assert(type < 2); - assert(index >= 0); - if (type == 0) { - assert(index < k_maxNumberOfDisplayedRows); - return &m_leafCells[index]; - } - assert(index < k_numberOfMenuRows); - return &m_nodeCells[index]; -} - -int VariableBoxController::ContentViewController::reusableCellCount(int type) { +int VariableBoxController::reusableCellCount(int type) { assert(type < 2); if (type == 0) { return k_maxNumberOfDisplayedRows; @@ -129,74 +53,93 @@ int VariableBoxController::ContentViewController::reusableCellCount(int type) { return k_numberOfMenuRows; } -void VariableBoxController::ContentViewController::willDisplayCellForIndex(HighlightCell * cell, int index) { +void VariableBoxController::willDisplayCellForIndex(HighlightCell * cell, int index) { if (m_currentPage == Page::RootMenu) { I18n::Message label = nodeLabelAtIndex(index); MessageTableCell * myCell = (MessageTableCell *)cell; myCell->setMessage(label); return; } - VariableBoxLeafCell * myCell = (VariableBoxLeafCell *)cell; - char label[3]; - putLabelAtIndexInBuffer(index, label); - myCell->setLabel(label); - if (m_currentPage == Page::Scalar) { - myCell->displayExpression(false); - const Expression evaluation = expressionForIndex(index); - char buffer[PrintFloat::k_maxComplexBufferLength]; - PoincareHelpers::Serialize(evaluation, buffer, PrintFloat::k_maxComplexBufferLength, Constant::ShortNumberOfSignificantDigits); - myCell->setSubtitle(buffer); - return; - } - assert(m_currentPage == Page::Matrix); - myCell->displayExpression(true); - /* TODO: implement list contexts */ - // TODO: handle matrix and scalar! - Layout layoutR = matrixLayoutAtIndex(index); - myCell->setLayout(layoutR); - if (layoutR.isUninitialized()) { - myCell->setSubtitle(I18n::translate(I18n::Message::Empty)); - } else { - char buffer[2*PrintFloat::bufferSizeForFloatsWithPrecision(2)+1]; - MatrixLayout matrixLayout = static_cast(layoutR); - int numberOfChars = PrintFloat::convertFloatToText(matrixLayout.numberOfRows(), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); - buffer[numberOfChars++] = 'x'; - PrintFloat::convertFloatToText(matrixLayout.numberOfColumns(), buffer+numberOfChars, PrintFloat::bufferSizeForFloatsWithPrecision(2), 2, Preferences::PrintFloatMode::Decimal); - myCell->setSubtitle(buffer); - } + ExpressionTableCellWithExpression * myCell = (ExpressionTableCellWithExpression *)cell; + Storage::Record record = recordAtIndex(index); + Layout symbolLayout = LayoutHelper::String(record.fullName(), strlen(record.fullName()) - strlen(extension())); + myCell->setLayout(symbolLayout); + myCell->setAccessoryLayout(expressionLayoutForIndex(selectedRow())); } -KDCoordinate VariableBoxController::ContentViewController::rowHeight(int index) { - if (m_currentPage == Page::RootMenu || m_currentPage == Page::Scalar) { - return Metric::ToolboxRowHeight; +KDCoordinate VariableBoxController::rowHeight(int index) { + if (m_currentPage != Page::RootMenu) { + Layout layoutR = expressionLayoutForIndex(index); + if (!layoutR.isUninitialized()) { + return max(layoutR.layoutSize().height()+k_leafMargin, Metric::ToolboxRowHeight); + } } - Layout layoutR = matrixLayoutAtIndex(index); - if (!layoutR.isUninitialized()) { - return max(layoutR.layoutSize().height()+k_leafMargin, Metric::ToolboxRowHeight); - } - return Metric::ToolboxRowHeight; + return NestedMenuController::rowHeight(index); } -int VariableBoxController::ContentViewController::typeAtLocation(int i, int j) { +int VariableBoxController::typeAtLocation(int i, int j) { if (m_currentPage == Page::RootMenu) { return 1; } return 0; } -void VariableBoxController::ContentViewController::reloadData() { - m_selectableTableView.reloadData(); +ExpressionTableCellWithExpression * VariableBoxController::leafCellAtIndex(int index) { + assert(index >= 0 && index < k_maxNumberOfDisplayedRows); + return &m_leafCells[index]; } -void VariableBoxController::ContentViewController::resetPage() { -#if MATRIX_VARIABLES +MessageTableCellWithChevron * VariableBoxController::nodeCellAtIndex(int index) { + assert(index >= 0 && index < k_numberOfMenuRows); + return &m_nodeCells[index]; +} + +VariableBoxController::Page VariableBoxController::pageAtIndex(int index) { + Page pages[2] = {Page::Expression, Page::Function}; + return pages[index]; +} + +bool VariableBoxController::selectSubMenu(int selectedRow) { + m_selectableTableView.deselectTable(); + m_currentPage = pageAtIndex(selectedRow); + return NestedMenuController::selectSubMenu(selectedRow); +} + +bool VariableBoxController::returnToPreviousMenu() { + m_selectableTableView.deselectTable(); m_currentPage = Page::RootMenu; -#else - m_currentPage = Page::Scalar; -#endif + return NestedMenuController::returnToPreviousMenu(); } -void VariableBoxController::ContentViewController::viewDidDisappear() { +bool VariableBoxController::selectLeaf(int selectedRow) { + m_selectableTableView.deselectTable(); + Storage::Record record = recordAtIndex(selectedRow); + sender()->handleEventWithText(record.fullName()); + app()->dismissModalViewController(); + return true; +} + +I18n::Message VariableBoxController::nodeLabelAtIndex(int index) { + assert(m_currentPage == Page::RootMenu); + I18n::Message labels[2] = {I18n::Message::Expressions, I18n::Message::Functions}; + return labels[index]; +} + +Layout VariableBoxController::expressionLayoutForIndex(int index) { + assert(m_currentPage != Page::RootMenu); + Storage::Record record = recordAtIndex(index); + return Expression::ExpressionFromRecord(record).createLayout(Poincare::Preferences::sharedPreferences()->displayMode(), Constant::ShortNumberOfSignificantDigits); +} + +const char * VariableBoxController::extension() const { + return m_currentPage == Page::Function ? GlobalContext::funcExtension : GlobalContext::expExtension; +} + +Storage::Record VariableBoxController::recordAtIndex(int rowIndex) { + return Storage::sharedStorage()->recordWithExtensionAtIndex(extension(), rowIndex); +} + +/* void VariableBoxController::viewDidDisappear() { m_selectableTableView.deselectTable(); // Tidy the memoized layouts to clean TreePool for (int i = 0; i < 10; i++) { // FIXME @@ -207,64 +150,10 @@ void VariableBoxController::ContentViewController::viewDidDisappear() { m_leafCells[i].setLayout(Layout()); } ViewController::viewDidDisappear(); -} + } -VariableBoxController::ContentViewController::Page VariableBoxController::ContentViewController::pageAtIndex(int index) { -#if LIST_VARIABLES - Page pages[3] = {Page::Scalar, Page::List, Page::Matrix}; -#else - Page pages[2] = {Page::Scalar, Page::Matrix}; -#endif - return pages[index]; -} -void VariableBoxController::ContentViewController::putLabelAtIndexInBuffer(int index, char * buffer) { - if (m_currentPage == Page::Scalar) { - buffer[0] = 'A' + index; - buffer[1] = 0; - } -#if LIST_VARIABLES - if (m_currentPage == Page::List) { - buffer[0] = 'L'; - buffer[1] = '0' + index; - buffer[2] = 0; - } -#endif - if (m_currentPage == Page::Matrix) { - buffer[0] = 'M'; - buffer[1] = '0' + index; - buffer[2] = 0; - } -} - -I18n::Message VariableBoxController::ContentViewController::nodeLabelAtIndex(int index) { - assert(m_currentPage == Page::RootMenu); -#if LIST_VARIABLES - I18n::Message labels[3] = {I18n::Message::Number, I18n::Message::List, I18n::Message::Matrix}; -#else - I18n::Message labels[2] = {I18n::Message::Number, I18n::Message::Matrix}; -#endif - return labels[index]; -} - -const Expression VariableBoxController::ContentViewController::expressionForIndex(int index) { - if (m_currentPage == Page::Scalar) { - const Symbol symbol = Symbol('A'+index); - return m_context->expressionForSymbol(symbol); - } - if (m_currentPage == Page::Matrix) { - const Symbol symbol = Symbol("M0",2); // FIXME Symbol::matrixSymbol('0'+(char)index); - return m_context->expressionForSymbol(symbol); - } -#if LIST_VARIABLES - if (m_currentPage == Page::List) { - return Expression(); - } -#endif - return Expression(); -} - -Layout VariableBoxController::ContentViewController::matrixLayoutAtIndex(int index) { +Layout VariableBoxController::matrixLayoutAtIndex(int index) { assert(m_currentPage == Page::Matrix); if (m_matrixLayouts[index].isUninitialized()) { const Expression evaluation = expressionForIndex(index); @@ -275,26 +164,5 @@ Layout VariableBoxController::ContentViewController::matrixLayoutAtIndex(int ind return m_matrixLayouts[index]; } -VariableBoxController::VariableBoxController(GlobalContext * context) : - StackViewController(nullptr, &m_contentViewController, KDColorWhite, Palette::PurpleBright, Palette::PurpleDark), - m_contentViewController(this, context) -{ -} +}*/ -void VariableBoxController::didBecomeFirstResponder() { - app()->setFirstResponder(&m_contentViewController); -} - -void VariableBoxController::setSender(Responder * sender) { - m_contentViewController.setSender(sender); -} - -void VariableBoxController::viewWillAppear() { - StackViewController::viewWillAppear(); - m_contentViewController.resetPage(); - m_contentViewController.reloadData(); -} - -void VariableBoxController::viewDidDisappear() { - StackViewController::viewDidDisappear(); -} diff --git a/apps/variable_box_controller.h b/apps/variable_box_controller.h index 926f73e76..2e669f0d8 100644 --- a/apps/variable_box_controller.h +++ b/apps/variable_box_controller.h @@ -5,68 +5,50 @@ #include #include -#include "variable_box_leaf_cell.h" #include "i18n.h" -class VariableBoxController : public StackViewController { +class VariableBoxController : public NestedMenuController { public: - VariableBoxController(Poincare::GlobalContext * context); - void didBecomeFirstResponder() override; - void setSender(Responder * sender); + VariableBoxController(); + + // View Controller void viewWillAppear() override; - void viewDidDisappear() override; + + // Responder + bool handleEvent(Ion::Events::Event event) override; + + //ListViewDataSource + int numberOfRows() override; + int reusableCellCount(int type) override; + void willDisplayCellForIndex(HighlightCell * cell, int index) override; + KDCoordinate rowHeight(int j) override; + int typeAtLocation(int i, int j) override; + + // Menu private: - class ContentViewController : public ViewController, public ListViewDataSource, public SelectableTableViewDataSource { - public: - ContentViewController(Responder * parentResponder, Poincare::GlobalContext * context); - View * view() override; - const char * title() override; - void didBecomeFirstResponder() override; - bool handleEvent(Ion::Events::Event event) override; - int numberOfRows() override; - HighlightCell * reusableCell(int index, int type) override; - int reusableCellCount(int type) override; - void willDisplayCellForIndex(HighlightCell * cell, int index) override; - KDCoordinate rowHeight(int j) override; - int typeAtLocation(int i, int j) override; - void setSender(Responder * responder) { m_sender = responder; } - void reloadData(); - void resetPage(); - void viewDidDisappear() override; - private: - enum class Page { - RootMenu, - Scalar, -#if LIST_VARIABLES - List, -#endif - Matrix + enum class Page { + RootMenu, + Expression, + Function }; - constexpr static int k_maxNumberOfDisplayedRows = 6; //240/Matrix::ToolboxRowHeight -#if LIST_VARIABLES - constexpr static int k_numberOfMenuRows = 3; -#else - constexpr static int k_numberOfMenuRows = 2; -#endif - constexpr static KDCoordinate k_leafMargin = 20; - Page pageAtIndex(int index); - void putLabelAtIndexInBuffer(int index, char * buffer); - I18n::Message nodeLabelAtIndex(int index); - const Poincare::Expression expressionForIndex(int index); - Poincare::Layout matrixLayoutAtIndex(int index); - Poincare::GlobalContext * m_context; - Responder * m_sender; - int m_firstSelectedRow; - int m_previousSelectedRow; - Page m_currentPage; - VariableBoxLeafCell m_leafCells[k_maxNumberOfDisplayedRows]; - MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; - // Matrix layout memoization - // FIXME - Poincare::Layout m_matrixLayouts[10]; - SelectableTableView m_selectableTableView; - }; - ContentViewController m_contentViewController; + constexpr static int k_maxNumberOfDisplayedRows = 6; //240/Metric::ToolboxRowHeight + constexpr static int k_numberOfMenuRows = 2; + constexpr static KDCoordinate k_leafMargin = 20; + ExpressionTableCellWithExpression * leafCellAtIndex(int index) override; + MessageTableCellWithChevron * nodeCellAtIndex(int index) override; + Page pageAtIndex(int index); + bool selectSubMenu(int selectedRow) override; + bool returnToPreviousMenu() override; + bool selectLeaf(int selectedRow) override; + I18n::Message nodeLabelAtIndex(int index); + Poincare::Layout expressionLayoutForIndex(int index); + const char * extension() const; + Ion::Storage::Record recordAtIndex(int rowIndex); + Page m_currentPage; + ExpressionTableCellWithExpression m_leafCells[k_maxNumberOfDisplayedRows]; + MessageTableCellWithChevron m_nodeCells[k_numberOfMenuRows]; + // Layout memoization + Poincare::Layout m_layouts[k_maxNumberOfDisplayedRows]; }; #endif diff --git a/apps/variables.de.i18n b/apps/variables.de.i18n index 6655c96d0..c35740687 100644 --- a/apps/variables.de.i18n +++ b/apps/variables.de.i18n @@ -1,4 +1,3 @@ Variables = "Variablen" -Number = "Zahlen" -Matrix = "Matrizen" -List = "Listen" +Expressions = "???" +Functions = "????" diff --git a/apps/variables.en.i18n b/apps/variables.en.i18n index 51ad23383..dc1dcb7b8 100644 --- a/apps/variables.en.i18n +++ b/apps/variables.en.i18n @@ -1,4 +1,3 @@ Variables = "Variables" -Number = "Numbers" -Matrix = "Matrices" -List = "Lists" +Expressions = "???" +Functions = "????" diff --git a/apps/variables.es.i18n b/apps/variables.es.i18n index 0955a00c1..dc1dcb7b8 100644 --- a/apps/variables.es.i18n +++ b/apps/variables.es.i18n @@ -1,4 +1,3 @@ Variables = "Variables" -Number = "Numeros" -Matrix = "Matrices" -List = "Listas" +Expressions = "???" +Functions = "????" diff --git a/apps/variables.fr.i18n b/apps/variables.fr.i18n index 68a1ef14e..fde91aaa8 100644 --- a/apps/variables.fr.i18n +++ b/apps/variables.fr.i18n @@ -1,4 +1,3 @@ Variables = "Variables" -Number = "Nombres" -Matrix = "Matrices" -List = "Listes" +Expressions = "Expressions" +Functions = "Functions" diff --git a/apps/variables.pt.i18n b/apps/variables.pt.i18n index 6cf69e5ef..68003b763 100644 --- a/apps/variables.pt.i18n +++ b/apps/variables.pt.i18n @@ -1,4 +1,3 @@ Variables = "Variaveis" -Number = "Numeros" -Matrix = "Matrizes" -List = "Listas" +Expressions = "???" +Functions = "????"