From 9a4873a3ecd9aa104bcf6c42fd81870aca9e6e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Tue, 7 Feb 2017 11:23:18 +0100 Subject: [PATCH] [apps/shared] Move part of apps/graph/list/list_controller to the shared folder to be used by sequence Change-Id: I3b2235d4869f7e589bad1fb31334d04c80e40dc3 --- apps/graph/list/list_controller.cpp | 237 ++++++---------------------- apps/graph/list/list_controller.h | 41 ++--- apps/shared/Makefile | 1 + apps/shared/list_controller.cpp | 192 ++++++++++++++++++++++ apps/shared/list_controller.h | 49 ++++++ 5 files changed, 295 insertions(+), 225 deletions(-) create mode 100644 apps/shared/list_controller.cpp create mode 100644 apps/shared/list_controller.h diff --git a/apps/graph/list/list_controller.cpp b/apps/graph/list/list_controller.cpp index 459adbf36..1e1154ce5 100644 --- a/apps/graph/list/list_controller.cpp +++ b/apps/graph/list/list_controller.cpp @@ -6,13 +6,10 @@ using namespace Shared; namespace Graph { -ListController::ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header) : - ViewController(parentResponder), - HeaderViewDelegate(header), +ListController::ListController(Responder * parentResponder, Shared::FunctionStore * functionStore, HeaderViewController * header) : + Shared::ListController(parentResponder, functionStore, header), m_functionTitleCells{FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator), FunctionTitleCell(FunctionTitleCell::Orientation::VerticalIndicator)}, - m_selectableTableView(SelectableTableView(this, this, 0, 0, 0, 0, nullptr, false, true)), - m_functionStore(functionStore), m_parameterController(ListParameterController(this, functionStore)) { } @@ -21,108 +18,48 @@ const char * ListController::title() const { return "Fonctions"; } -View * ListController::view() { - return &m_selectableTableView; -} - -Responder * ListController::tabController() const{ - return (parentResponder()->parentResponder()->parentResponder()); -} - -StackViewController * ListController::stackController() const{ - return (StackViewController *)(parentResponder()->parentResponder()); -} - -int ListController::numberOfRows() { - return 1 + m_functionStore->numberOfFunctions(); -}; - -int ListController::numberOfColumns() { - return 2; -}; - -KDCoordinate ListController::rowHeight(int j) { - if (j == numberOfRows() - 1) { - return k_emptyRowHeight; +bool ListController::handleEvent(Ion::Events::Event event) { + if (Shared::ListController::handleEvent(event)) { + return true; } - Function * function = m_functionStore->functionAtIndex(j); - if (function->layout() == nullptr) { - return k_emptyRowHeight; + if (event == Ion::Events::OK) { + return handleEnter(); } - KDCoordinate functionSize = function->layout()->size().height(); - return functionSize + k_emptyRowHeight - KDText::stringSize(" ").height(); + if ((!event.hasText() && event != Ion::Events::XNT) || m_selectableTableView.selectedColumn() == 0 + || m_selectableTableView.selectedRow() == numberOfRows() - 1) { + return false; + } + FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow())); + editExpression(functionCell, event); + return true; } -KDCoordinate ListController::columnWidth(int i) { - switch (i) { +bool ListController::handleEnter() { + switch (m_selectableTableView.selectedColumn()) { case 0: - return k_functionNameWidth; + { + if (m_selectableTableView.selectedRow() == numberOfRows() - 1) { + return true; + } + configureFunction(m_functionStore->functionAtIndex(m_selectableTableView.selectedRow())); + return true; + } case 1: - return m_selectableTableView.bounds().width()-k_functionNameWidth; + { + if (m_selectableTableView.selectedRow() == numberOfRows() - 1) { + return addFunction(); + } + FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow())); + editExpression(functionCell, Ion::Events::OK); + return true; + } default: - assert(false); - return 0; - } -} - -KDCoordinate ListController::cumulatedWidthFromIndex(int i) { - switch (i) { - case 0: - return 0; - case 1: - return k_functionNameWidth; - case 2: - return m_selectableTableView.bounds().width(); - default: - assert(false); - return 0; - } -} - -KDCoordinate ListController::cumulatedHeightFromIndex(int j) { - int result = 0; - for (int k = 0; k < j; k++) { - result += rowHeight(k); - } - return result; -} - -int ListController::indexFromCumulatedWidth(KDCoordinate offsetX) { - if (offsetX <= k_functionNameWidth) { - return 0; - } else { - if (offsetX <= m_selectableTableView.bounds().width()) - return 1; - else { - return 2; + { + return false; } } } -int ListController::indexFromCumulatedHeight(KDCoordinate offsetY) { - int result = 0; - int j = 0; - while (result < offsetY && j < numberOfRows()) { - result += rowHeight(j++); - } - return (result < offsetY || offsetY == 0) ? j : j - 1; -} - -void ListController::didBecomeFirstResponder() { - if (m_selectableTableView.selectedRow() == -1) { - m_selectableTableView.selectCellAtLocation(1, 0); - } else { - m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); - } - app()->setFirstResponder(&m_selectableTableView); -} - -void ListController::configureFunction(Function * function) { - StackViewController * stack = stackController(); - m_parameterController.setFunction(function); - stack->push(&m_parameterController); -} - void ListController::editExpression(FunctionExpressionCell * functionCell, Ion::Events::Event event) { char * initialText = nullptr; char initialTextContent[255]; @@ -146,108 +83,22 @@ void ListController::editExpression(FunctionExpressionCell * functionCell, Ion:: m_selectableTableView.dataHasChanged(true); } -bool ListController::handleEvent(Ion::Events::Event event) { - if (event == Ion::Events::Up) { - m_selectableTableView.deselectTable(); - assert(m_selectableTableView.selectedRow() == -1); - app()->setFirstResponder(tabController()); - return true; - } - if (event == Ion::Events::OK) { - return handleEnter(); - } - if ((!event.hasText() && event != Ion::Events::XNT) || m_selectableTableView.selectedColumn() == 0 - || m_selectableTableView.selectedRow() == numberOfRows() - 1) { - return false; - } - FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow())); - editExpression(functionCell, event); - return true; +ListParameterController * ListController::parameterController() { + return &m_parameterController; } -bool ListController::handleEnter() { - switch (m_selectableTableView.selectedColumn()) { - case 0: - { - if (m_selectableTableView.selectedRow() == numberOfRows() - 1) { - return true; - } - configureFunction(m_functionStore->functionAtIndex(m_selectableTableView.selectedRow())); - // Force to reload the table (deleted functions, desactivated function) - m_selectableTableView.dataHasChanged(true); - return true; - } - case 1: - { - if (m_selectableTableView.selectedRow() == numberOfRows() - 1) { - if (m_functionStore->numberOfFunctions() < FunctionStore::k_maxNumberOfFunctions) { - m_functionStore->addEmptyFunction(); - m_selectableTableView.reloadData(); - return true; - } - // Add a warning to tell the user there is no more space for new functions - return false; - } - FunctionExpressionCell * functionCell = (FunctionExpressionCell *)(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow())); - editExpression(functionCell, Ion::Events::OK); - return true; - } - default: - { - return false; - } - } -} - -int ListController::typeAtLocation(int i, int j) { - if (j == numberOfRows() - 1) { - return i + 2; - } - return i; -} - -TableViewCell * ListController::reusableCell(int index, int type) { - assert(index >= 0); - assert(index < k_maxNumberOfRows); - switch (type) { - case 0: - return &m_functionTitleCells[index]; - case 1: - return &m_expressionCells[index]; - case 2: - return &m_emptyCell; - case 3: - return &m_addNewFunction; - default: - assert(false); - return nullptr; - } -} - -int ListController::reusableCellCount(int type) { - if (type > 1) { - return 1; - } +int ListController::maxNumberOfRows() { return k_maxNumberOfRows; } -void ListController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { - if (j < numberOfRows() - 1) { - if (i == 0) { - FunctionTitleCell * myFunctionCell = (FunctionTitleCell *)cell; - Function * function = m_functionStore->functionAtIndex(j); - char bufferName[5] = {*function->name(),'(','x',')', 0}; - myFunctionCell->setText(bufferName); - KDColor functionNameColor = function->isActive() ? function->color() : Palette::GreyDark; - myFunctionCell->setColor(functionNameColor); - } else { - FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell; - myCell->setFunction(m_functionStore->functionAtIndex(j)); - } - } - EvenOddCell * myCell = (EvenOddCell *)cell; - myCell->setEven(j%2 == 0); - myCell->setHighlighted(i == m_selectableTableView.selectedColumn() && j == m_selectableTableView.selectedRow()); +TableViewCell * ListController::titleCells(int index) { + assert(index >= 0 && index < k_maxNumberOfRows); + return &m_functionTitleCells[index]; +} + +TableViewCell * ListController::expressionCells(int index) { + assert(index >= 0 && index < k_maxNumberOfRows); + return &m_expressionCells[index]; } } diff --git a/apps/graph/list/list_controller.h b/apps/graph/list/list_controller.h index 342115113..f95b15805 100644 --- a/apps/graph/list/list_controller.h +++ b/apps/graph/list/list_controller.h @@ -2,52 +2,29 @@ #define GRAPH_LIST_CONTROLLER_H #include -#include "../function_store.h" #include "../../shared/function_title_cell.h" #include "../../shared/function_expression_cell.h" #include "../../shared/new_function_cell.h" +#include "../../shared/list_controller.h" #include "../../shared/list_parameter_controller.h" namespace Graph { -class ListController : public ViewController, public HeaderViewDelegate, public TableViewDataSource { +class ListController : public Shared::ListController { public: - ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header); + ListController(Responder * parentResponder, Shared::FunctionStore * functionStore, HeaderViewController * header); const char * title() const override; bool handleEvent(Ion::Events::Event event) override; - bool handleEnter(); - void didBecomeFirstResponder() override; - virtual View * view() override; - - int numberOfRows() override; - int numberOfColumns() override; - void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; - KDCoordinate columnWidth(int i) override; - KDCoordinate rowHeight(int j) override; - KDCoordinate cumulatedWidthFromIndex(int i) override; - KDCoordinate cumulatedHeightFromIndex(int j) override; - int indexFromCumulatedWidth(KDCoordinate offsetX) override; - int indexFromCumulatedHeight(KDCoordinate offsetY) override; - TableViewCell * reusableCell(int index, int type) override; - int reusableCellCount(int type) override; - int typeAtLocation(int i, int j) override; - void configureFunction(Function * function); - void editExpression(Shared::FunctionExpressionCell * functionCell, Ion::Events::Event event); - private: - static constexpr KDCoordinate k_functionNameWidth = 65; - static constexpr KDCoordinate k_emptyRowHeight = 50; - Responder * tabController() const; - StackViewController * stackController() const; + bool handleEnter(); + void editExpression(Shared::FunctionExpressionCell * functionCell, Ion::Events::Event event); + Shared::ListParameterController * parameterController() override; + int maxNumberOfRows() override; + TableViewCell * titleCells(int index) override; + TableViewCell * expressionCells(int index) override; constexpr static int k_maxNumberOfRows = 5; - // !!! CAUTION: The order here is important - // The cells should be initialized *before* the TableView! Shared::FunctionTitleCell m_functionTitleCells[k_maxNumberOfRows]; Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfRows]; - EvenOddCell m_emptyCell; - Shared::NewFunctionCell m_addNewFunction; - SelectableTableView m_selectableTableView; - FunctionStore * m_functionStore; Shared::ListParameterController m_parameterController; }; diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 79c9ec34b..60c1a9558 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -14,6 +14,7 @@ app_objs += $(addprefix apps/shared/,\ function_title_cell.o\ interactive_curve_view_controller.o\ interactive_curve_view_range.o\ + list_controller.o\ list_parameter_controller.o\ memoized_curve_view_range.o\ new_function_cell.o\ diff --git a/apps/shared/list_controller.cpp b/apps/shared/list_controller.cpp new file mode 100644 index 000000000..b9d4b16ad --- /dev/null +++ b/apps/shared/list_controller.cpp @@ -0,0 +1,192 @@ +#include "list_controller.h" +#include "function_title_cell.h" +#include "function_expression_cell.h" +#include + +namespace Shared { + +ListController::ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header) : + ViewController(parentResponder), + HeaderViewDelegate(header), + m_selectableTableView(SelectableTableView(this, this, 0, 0, 0, 0, nullptr, false, true)), + m_functionStore(functionStore) +{ +} + +View * ListController::view() { + return &m_selectableTableView; +} + +int ListController::numberOfRows() { + return 1 + m_functionStore->numberOfFunctions(); +}; + +int ListController::numberOfColumns() { + return 2; +}; + +KDCoordinate ListController::rowHeight(int j) { + if (j == numberOfRows() - 1) { + return k_emptyRowHeight; + } + Function * function = m_functionStore->functionAtIndex(j); + if (function->layout() == nullptr) { + return k_emptyRowHeight; + } + KDCoordinate functionSize = function->layout()->size().height(); + return functionSize + k_emptyRowHeight - KDText::stringSize(" ").height(); +} + +KDCoordinate ListController::columnWidth(int i) { + switch (i) { + case 0: + return k_functionNameWidth; + case 1: + return m_selectableTableView.bounds().width()-k_functionNameWidth; + default: + assert(false); + return 0; + } +} + +KDCoordinate ListController::cumulatedWidthFromIndex(int i) { + switch (i) { + case 0: + return 0; + case 1: + return k_functionNameWidth; + case 2: + return m_selectableTableView.bounds().width(); + default: + assert(false); + return 0; + } +} + +KDCoordinate ListController::cumulatedHeightFromIndex(int j) { + int result = 0; + for (int k = 0; k < j; k++) { + result += rowHeight(k); + } + return result; +} + +int ListController::indexFromCumulatedWidth(KDCoordinate offsetX) { + if (offsetX <= k_functionNameWidth) { + return 0; + } else { + if (offsetX <= m_selectableTableView.bounds().width()) + return 1; + else { + return 2; + } + } +} + +int ListController::indexFromCumulatedHeight(KDCoordinate offsetY) { + int result = 0; + int j = 0; + while (result < offsetY && j < numberOfRows()) { + result += rowHeight(j++); + } + return (result < offsetY || offsetY == 0) ? j : j - 1; +} + +int ListController::typeAtLocation(int i, int j) { + if (j == numberOfRows() - 1) { + return i + 2; + } + return i; +} + +TableViewCell * ListController::reusableCell(int index, int type) { + assert(index >= 0); + assert(index < maxNumberOfRows()); + switch (type) { + case 0: + return titleCells(index); + case 1: + return expressionCells(index); + case 2: + return &m_emptyCell; + case 3: + return &m_addNewFunction; + default: + assert(false); + return nullptr; + } +} + +int ListController::reusableCellCount(int type) { + if (type > 1) { + return 1; + } + return maxNumberOfRows(); +} + +void ListController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { + if (j < numberOfRows() - 1) { + if (i == 0) { + FunctionTitleCell * myFunctionCell = (FunctionTitleCell *)cell; + Function * function = m_functionStore->functionAtIndex(j); + char bufferName[5] = {*function->name(),'(','x',')', 0}; + myFunctionCell->setText(bufferName); + KDColor functionNameColor = function->isActive() ? function->color() : Palette::GreyDark; + myFunctionCell->setColor(functionNameColor); + } else { + FunctionExpressionCell * myCell = (FunctionExpressionCell *)cell; + myCell->setFunction(m_functionStore->functionAtIndex(j)); + } + } + EvenOddCell * myCell = (EvenOddCell *)cell; + myCell->setEven(j%2 == 0); + myCell->setHighlighted(i == m_selectableTableView.selectedColumn() && j == m_selectableTableView.selectedRow()); +} + +void ListController::didBecomeFirstResponder() { + if (m_selectableTableView.selectedRow() == -1) { + m_selectableTableView.selectCellAtLocation(1, 0); + } else { + m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + } + app()->setFirstResponder(&m_selectableTableView); +} + +bool ListController::addFunction() { + if (m_functionStore->numberOfFunctions() < m_functionStore->maxNumberOfFunctions()) { + m_functionStore->addEmptyFunction(); + m_selectableTableView.reloadData(); + return true; + } + // Add a warning to tell the user there is no more space for new functions + app()->displayWarning("Nombre maximal d'éléments atteint"); + return false; +} + +void ListController::configureFunction(Function * function) { + StackViewController * stack = stackController(); + parameterController()->setFunction(function); + stack->push(parameterController()); + // Force to reload the table (deleted functions, desactivated function) + m_selectableTableView.dataHasChanged(true); +} + +bool ListController::handleEvent(Ion::Events::Event event) { + if (event == Ion::Events::Up) { + m_selectableTableView.deselectTable(); + assert(m_selectableTableView.selectedRow() == -1); + app()->setFirstResponder(tabController()); + return true; + } + return false; +} + +Responder * ListController::tabController() const{ + return (parentResponder()->parentResponder()->parentResponder()); +} + +StackViewController * ListController::stackController() const{ + return (StackViewController *)(parentResponder()->parentResponder()); +} + +} diff --git a/apps/shared/list_controller.h b/apps/shared/list_controller.h new file mode 100644 index 000000000..3d861a8dd --- /dev/null +++ b/apps/shared/list_controller.h @@ -0,0 +1,49 @@ +#ifndef SHARED_LIST_CONTROLLER_H +#define SHARED_LIST_CONTROLLER_H + +#include +#include "function_store.h" +#include "list_parameter_controller.h" +#include "new_function_cell.h" + +namespace Shared { + +class ListController : public ViewController, public HeaderViewDelegate, public TableViewDataSource { +public: + ListController(Responder * parentResponder, FunctionStore * functionStore, HeaderViewController * header); + View * view() override; + int numberOfRows() override; + int numberOfColumns() override; + KDCoordinate rowHeight(int j) override; + KDCoordinate columnWidth(int i) override; + KDCoordinate cumulatedWidthFromIndex(int i) override; + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedWidth(KDCoordinate offsetX) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + int typeAtLocation(int i, int j) override; + TableViewCell * reusableCell(int index, int type) override; + int reusableCellCount(int type) override; + void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; + void didBecomeFirstResponder() override; + bool handleEvent(Ion::Events::Event event) override; +protected: + bool addFunction(); + void configureFunction(Function * function); + SelectableTableView m_selectableTableView; + FunctionStore * m_functionStore; +private: + static constexpr KDCoordinate k_functionNameWidth = 65; + static constexpr KDCoordinate k_emptyRowHeight = 50; + Responder * tabController() const; + StackViewController * stackController() const; + virtual ListParameterController * parameterController() = 0; + virtual int maxNumberOfRows() = 0; + virtual TableViewCell * titleCells(int index) = 0; + virtual TableViewCell * expressionCells(int index) = 0; + EvenOddCell m_emptyCell; + NewFunctionCell m_addNewFunction; +}; + +} + +#endif