From 38d0310e37e34a39422feb5a5e1eddc209d5e008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 19 Dec 2016 17:28:27 +0100 Subject: [PATCH] [apps] Create a class editable cell table view controller Change-Id: I69eec933e0aa47317e7ba48b08dd840309a0adf7 --- apps/Makefile | 1 + apps/editable_cell_table_view_controller.cpp | 100 +++++++++++++++++++ apps/editable_cell_table_view_controller.h | 33 ++++++ 3 files changed, 134 insertions(+) create mode 100644 apps/editable_cell_table_view_controller.cpp create mode 100644 apps/editable_cell_table_view_controller.h diff --git a/apps/Makefile b/apps/Makefile index 07e3eb1d2..61d173693 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -9,6 +9,7 @@ app_objs += $(addprefix apps/,\ apps_container.o\ constant.o\ curve_view.o\ + editable_cell_table_view_controller.o\ expression_text_field_delegate.o\ float_parameter_controller.o\ main.o\ diff --git a/apps/editable_cell_table_view_controller.cpp b/apps/editable_cell_table_view_controller.cpp new file mode 100644 index 000000000..ba22024db --- /dev/null +++ b/apps/editable_cell_table_view_controller.cpp @@ -0,0 +1,100 @@ +#include "editable_cell_table_view_controller.h" +#include "apps_container.h" +#include "constant.h" +#include "text_field_delegate_app.h" +#include + +EditableCellTableViewController::EditableCellTableViewController(Responder * parentResponder, KDCoordinate topMargin, + KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) : + ViewController(parentResponder), + m_selectableTableView(SelectableTableView(this, this, topMargin, rightMargin, bottomMargin, leftMargin, this)) +{ +} + +View * EditableCellTableViewController::view() { + return &m_selectableTableView; +} + +bool EditableCellTableViewController::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { + TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app(); + return myApp->textFieldDidReceiveEvent(textField, event); +} + +bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text) { + AppsContainer * appsContainer = (AppsContainer *)app()->container(); + Context * globalContext = appsContainer->globalContext(); + float floatBody = Expression::parse(text)->approximate(*globalContext); + setElementLinkedToCellLocationInModel(floatBody, m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + willDisplayCellAtLocation(m_selectableTableView.cellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()), m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); + m_selectableTableView.reloadData(); + return true; +} + +void EditableCellTableViewController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) { + if (cellAtLocationIsEditable(previousSelectedCellX, previousSelectedCellY)) { + EvenOddEditableTextCell * myCell = (EvenOddEditableTextCell *)t->cellAtLocation(previousSelectedCellX, previousSelectedCellY); + myCell->setEditing(false); + app()->setFirstResponder(t); + } + if (cellAtLocationIsEditable(t->selectedColumn(), t->selectedRow())) { + EvenOddEditableTextCell * myCell = (EvenOddEditableTextCell *)t->cellAtLocation(t->selectedColumn(), t->selectedRow()); + app()->setFirstResponder(myCell); + } +} + +int EditableCellTableViewController::numberOfRows() { + int numberOfModelElements = modelNumberOfElements(); + if (numberOfModelElements >= modelMaxNumberOfElements()) { + return 1 + numberOfModelElements; + } + return 2 + numberOfModelElements; +} + +KDCoordinate EditableCellTableViewController::rowHeight(int j) { + return k_cellHeight; +} + +KDCoordinate EditableCellTableViewController::cumulatedHeightFromIndex(int j) { + return j*k_cellHeight; +} + +int EditableCellTableViewController::indexFromCumulatedHeight(KDCoordinate offsetY) { + return (offsetY-1) / k_cellHeight; +} + +void EditableCellTableViewController::willDisplayCellAtLocation(TableViewCell * cell, int i, int j) { + EvenOddCell * myCell = (EvenOddCell *)cell; + myCell->setEven(j%2 == 0); + // The cell is editable + if (cellAtLocationIsEditable(i, j)) { + EvenOddEditableTextCell * myEditableValueCell = (EvenOddEditableTextCell *)cell; + char buffer[Constant::FloatBufferSizeInScientificMode]; + // Special case 1: last row + if (j == numberOfRows() - 1) { + /* Display an empty line only if there is enough space for a new element in + * data */ + int numberOfElements = modelNumberOfElements(); + if (numberOfElements < modelMaxNumberOfElements()) { + buffer[0] = 0; + myEditableValueCell->setText(buffer); + return; + } + } + Float(elementInModelLinkedToCellLocation(i, j)).convertFloatToText(buffer, Constant::FloatBufferSizeInScientificMode, Constant::NumberOfDigitsInMantissaInScientificMode); + myEditableValueCell->setText(buffer); + return; + } +} + +void EditableCellTableViewController::didBecomeFirstResponder() { + if (m_selectableTableView.selectedRow() == -1) { + m_selectableTableView.selectCellAtLocation(0, 0); + } else { + int selectedRow = m_selectableTableView.selectedRow(); + selectedRow = selectedRow >= numberOfRows() ? numberOfRows()-1 : selectedRow; + int selectedColumn = m_selectableTableView.selectedColumn(); + selectedColumn = selectedColumn >= numberOfColumns() ? numberOfColumns() - 1 : selectedColumn; + m_selectableTableView.selectCellAtLocation(selectedColumn, selectedRow); + } + app()->setFirstResponder(&m_selectableTableView); +} diff --git a/apps/editable_cell_table_view_controller.h b/apps/editable_cell_table_view_controller.h new file mode 100644 index 000000000..1a26618a7 --- /dev/null +++ b/apps/editable_cell_table_view_controller.h @@ -0,0 +1,33 @@ +#ifndef APPS_EDITABLE_CELL_TABLE_VIEW_CONTROLLER_H +#define APPS_EDITABLE_CELL_TABLE_VIEW_CONTROLLER_H + +#include + +class EditableCellTableViewController : public ViewController, public TableViewDataSource, public SelectableTableViewDelegate, public TextFieldDelegate { +public: + EditableCellTableViewController(Responder * parentResponder, KDCoordinate topMargin, + KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin); + virtual View * view() override; + + bool textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) override; + bool textFieldDidFinishEditing(TextField * textField, const char * text) override; + void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; + + int numberOfRows() override; + void willDisplayCellAtLocation(TableViewCell * cell, int i, int j) override; + KDCoordinate rowHeight(int j) override; + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + + void didBecomeFirstResponder() override; +protected: + static constexpr KDCoordinate k_cellHeight = 30; + virtual bool cellAtLocationIsEditable(int columnIndex, int rowIndex) = 0; + virtual void setElementLinkedToCellLocationInModel(float floatBody, int columnIndex, int rowIndex) = 0; + virtual float elementInModelLinkedToCellLocation(int columnIndex, int rowIndex) = 0; + virtual int modelNumberOfElements() = 0; + virtual int modelMaxNumberOfElements() const = 0; + SelectableTableView m_selectableTableView; +}; + +#endif