From 933838ff5e653906dba862eb4359ffdbedaa563f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 16 Oct 2018 15:43:30 +0200 Subject: [PATCH] [apps/graph] Rename functions --- apps/graph/list/list_parameter_controller.cpp | 9 ++++ apps/graph/list/list_parameter_controller.h | 7 ++- apps/graph/list/storage_list_controller.cpp | 50 ++++++++++++++++++- apps/graph/list/storage_list_controller.h | 13 +++-- .../list/text_field_function_title_cell.cpp | 15 ++++++ .../list/text_field_function_title_cell.h | 12 ++--- apps/shared/storage_cartesian_function.h | 1 + .../shared/storage_function_list_controller.h | 2 +- ion/include/ion/storage.h | 3 ++ 9 files changed, 98 insertions(+), 14 deletions(-) diff --git a/apps/graph/list/list_parameter_controller.cpp b/apps/graph/list/list_parameter_controller.cpp index ac99075cc..eeb8706f2 100644 --- a/apps/graph/list/list_parameter_controller.cpp +++ b/apps/graph/list/list_parameter_controller.cpp @@ -1,4 +1,5 @@ #include "list_parameter_controller.h" +#include "storage_list_controller.h" #include using namespace Shared; @@ -14,9 +15,17 @@ HighlightCell * ListParameterController::reusableCell(int index) { bool ListParameterController::handleEnterOnRow(int rowIndex) { if (rowIndex == 0) { + renameFunction(); return true; } return StorageListParameterController::handleEnterOnRow(rowIndex-1); } +void ListParameterController::renameFunction() { + // Set editing true on function title + StackViewController * stack = (StackViewController *)(parentResponder()); + stack->pop(); + m_listController->renameSelectedFunction(); +} + } diff --git a/apps/graph/list/list_parameter_controller.h b/apps/graph/list/list_parameter_controller.h index ec71de6e2..a69d95e75 100644 --- a/apps/graph/list/list_parameter_controller.h +++ b/apps/graph/list/list_parameter_controller.h @@ -5,10 +5,13 @@ namespace Graph { +class StorageListController; + class ListParameterController : public Shared::StorageListParameterController { public: - ListParameterController(Responder * parentResponder, Shared::StorageFunctionStore * functionStore, I18n::Message functionColorMessage, I18n::Message deleteFunctionMessage, SelectableTableViewDelegate * tableDelegate = nullptr) : + ListParameterController(StorageListController * listController, Responder * parentResponder, Shared::StorageFunctionStore * functionStore, I18n::Message functionColorMessage, I18n::Message deleteFunctionMessage, SelectableTableViewDelegate * tableDelegate = nullptr) : Shared::StorageListParameterController(parentResponder, functionStore, functionColorMessage, deleteFunctionMessage, tableDelegate), + m_listController(listController), m_renameCell(I18n::Message::Rename) {} HighlightCell * reusableCell(int index) override; @@ -18,6 +21,8 @@ private: int totalNumberOfCells() const override { return Shared::StorageListParameterController::totalNumberOfCells() + 1; } + void renameFunction(); + StorageListController * m_listController; MessageTableCell m_renameCell; }; diff --git a/apps/graph/list/storage_list_controller.cpp b/apps/graph/list/storage_list_controller.cpp index 7c1359a9c..f92b369d5 100644 --- a/apps/graph/list/storage_list_controller.cpp +++ b/apps/graph/list/storage_list_controller.cpp @@ -10,9 +10,15 @@ namespace Graph { StorageListController::StorageListController(Responder * parentResponder, StorageCartesianFunctionStore * functionStore, ButtonRowController * header, ButtonRowController * footer) : Shared::StorageFunctionListController(parentResponder, functionStore, header, footer, I18n::Message::AddFunction), - m_functionTitleCells{}, + m_functionTitleCells{ //TODO find better initialization + TextFieldFunctionTitleCell(this), + TextFieldFunctionTitleCell(this), + TextFieldFunctionTitleCell(this), + TextFieldFunctionTitleCell(this), + TextFieldFunctionTitleCell(this), + }, m_expressionCells{}, - m_parameterController(this, functionStore, I18n::Message::FunctionColor, I18n::Message::DeleteFunction) + m_parameterController(this, this, functionStore, I18n::Message::FunctionColor, I18n::Message::DeleteFunction) { for (int i = 0; i < k_maxNumberOfDisplayableRows; i++) { m_expressionCells[i].setLeftMargin(k_expressionMargin); @@ -23,6 +29,46 @@ const char * StorageListController::title() { return I18n::translate(I18n::Message::FunctionTab); } +void StorageListController::renameSelectedFunction() { + assert(selectedColumn() == 0); + assert(selectedRow() >= 0 && selectedRow() < numberOfRows()-1); // TODO change if sometimes the addFunction row is not displayed + TextFieldFunctionTitleCell * selectedTitleCell = (TextFieldFunctionTitleCell *)(selectableTableView()->selectedCell()); + app()->setFirstResponder(selectedTitleCell); + selectedTitleCell->setEditing(true); +} + +bool StorageListController::textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) { + // Compute the new name + size_t textLength = strlen(text); + size_t argumentLength = strlen("(x)"); //TODO + constexpr int maxBaseNameSize = StorageFunction::k_maxNameWithArgumentSize; + char baseName[maxBaseNameSize]; + if (textLength <= argumentLength) { + // The user entered an empty name. Use a default function name. + StorageCartesianFunction::DefaultName(baseName, maxBaseNameSize); + } else { + strlcpy(baseName, text, textLength - argumentLength + 1); + } + + // Set the name + Ion::Storage::Record::ErrorStatus error = StorageCartesianFunction::baseNameCompliant(baseName) ? m_functionStore->modelAtIndex(m_selectableTableView.selectedRow())->setBaseNameWithExtension(baseName, GlobalContext::funcExtension /*TODO store elsewhere?*/) : Ion::Storage::Record::ErrorStatus::NonCompliantName; + + // Handle any error + if (error == Ion::Storage::Record::ErrorStatus::None) { + m_selectableTableView.selectedCell()->setHighlighted(true); + app()->setFirstResponder(&m_selectableTableView); + return true; + } else if (error == Ion::Storage::Record::ErrorStatus::NameTaken) { + app()->displayWarning(I18n::Message::NameTaken); + } else if (error == Ion::Storage::Record::ErrorStatus::NonCompliantName) { + app()->displayWarning(I18n::Message::NonCompliantName); + } else { + assert(error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable); + app()->displayWarning(I18n::Message::NameTooLong); + } + return false; +} + StorageListParameterController * StorageListController::parameterController() { return &m_parameterController; } diff --git a/apps/graph/list/storage_list_controller.h b/apps/graph/list/storage_list_controller.h index a15c83b5c..a326a8b4e 100644 --- a/apps/graph/list/storage_list_controller.h +++ b/apps/graph/list/storage_list_controller.h @@ -5,24 +5,29 @@ #include "list_parameter_controller.h" #include "text_field_function_title_cell.h" #include "../storage_cartesian_function_store.h" -#include -#include #include +#include +#include namespace Graph { -class StorageListController : public Shared::StorageFunctionListController { +class StorageListController : public Shared::StorageFunctionListController, public Shared::TextFieldDelegate { public: StorageListController(Responder * parentResponder, StorageCartesianFunctionStore * functionStore, ButtonRowController * header, ButtonRowController * footer); const char * title() override; + void renameSelectedFunction(); + bool textFieldDidFinishEditing(TextField * textField, const char * text, Ion::Events::Event event) override; private: + constexpr static int k_maxNumberOfDisplayableRows = 5; Shared::StorageListParameterController * parameterController() override; int maxNumberOfDisplayableRows() override; Shared::FunctionTitleCell * titleCells(int index) override; HighlightCell * expressionCells(int index) override; void willDisplayTitleCellAtIndex(HighlightCell * cell, int j) override; void willDisplayExpressionCellAtIndex(HighlightCell * cell, int j) override; - constexpr static int k_maxNumberOfDisplayableRows = 5; + Shared::TextFieldDelegateApp * textFieldDelegateApp() override { + return static_cast(app()); + } TextFieldFunctionTitleCell m_functionTitleCells[k_maxNumberOfDisplayableRows]; Shared::FunctionExpressionCell m_expressionCells[k_maxNumberOfDisplayableRows]; ListParameterController m_parameterController; diff --git a/apps/graph/list/text_field_function_title_cell.cpp b/apps/graph/list/text_field_function_title_cell.cpp index 8c5daf2b9..03290868b 100644 --- a/apps/graph/list/text_field_function_title_cell.cpp +++ b/apps/graph/list/text_field_function_title_cell.cpp @@ -1,13 +1,28 @@ #include "text_field_function_title_cell.h" +#include "storage_list_controller.h" #include namespace Graph { +TextFieldFunctionTitleCell::TextFieldFunctionTitleCell(StorageListController * listController, Orientation orientation, KDText::FontSize size) : + Shared::FunctionTitleCell(orientation), + Responder(listController), + m_textField(this, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, listController, false, size, 0.5f, 0.5f) + {} + void TextFieldFunctionTitleCell::setHighlighted(bool highlight) { EvenOddCell::setHighlighted(highlight); m_textField.setBackgroundColor(EvenOddCell::backgroundColor()); } +void TextFieldFunctionTitleCell::setEditing(bool editing) { + app()->setFirstResponder(&m_textField); + const char * previousText = m_textField.text(); + m_textField.setEditing(true, false); + m_textField.setText(previousText); + m_textField.setCursorLocation(strlen(previousText) - strlen("(x)")); +} + void TextFieldFunctionTitleCell::setEven(bool even) { EvenOddCell::setEven(even); m_textField.setBackgroundColor(EvenOddCell::backgroundColor()); diff --git a/apps/graph/list/text_field_function_title_cell.h b/apps/graph/list/text_field_function_title_cell.h index 7b62f9073..2d67692c7 100644 --- a/apps/graph/list/text_field_function_title_cell.h +++ b/apps/graph/list/text_field_function_title_cell.h @@ -1,16 +1,16 @@ #ifndef GRAPH_LIST_TEXT_FIELD_FUNCTION_TITLE_CELL_H #define GRAPH_LIST_TEXT_FIELD_FUNCTION_TITLE_CELL_H -#include "../../shared/function_title_cell.h" +#include namespace Graph { -class TextFieldFunctionTitleCell : public Shared::FunctionTitleCell { +class StorageListController; + +class TextFieldFunctionTitleCell : public Shared::FunctionTitleCell, public Responder { public: - TextFieldFunctionTitleCell(Orientation orientation = Orientation::VerticalIndicator, KDText::FontSize size = KDText::FontSize::Large) : - Shared::FunctionTitleCell(orientation), - m_textField(nullptr, m_textFieldBuffer, m_textFieldBuffer, k_textFieldBufferSize, nullptr, false, size, 0.5f, 0.5f) - {} + TextFieldFunctionTitleCell(StorageListController * listController, Orientation orientation = Orientation::VerticalIndicator, KDText::FontSize size = KDText::FontSize::Large); + void setEditing(bool editing); void setEven(bool even) override; void setHighlighted(bool highlight) override; void setColor(KDColor color) override; diff --git a/apps/shared/storage_cartesian_function.h b/apps/shared/storage_cartesian_function.h index 107a0c534..630470d3a 100644 --- a/apps/shared/storage_cartesian_function.h +++ b/apps/shared/storage_cartesian_function.h @@ -14,6 +14,7 @@ public: StorageCartesianFunction(Ion::Storage::Record record = Record()) : StorageFunction(record) {} + static bool baseNameCompliant(const char * baseName) { return true; } // TODO TODO TODO //bool operator==(const StorageCartesianFunction & other) const { return *(static_cast(this)) == static_cast(other)); } //bool operator!=(const StorageCartesianFunction & other) const { return !(*(static_cast(this)) == static_cast(other)); } bool displayDerivative() const; diff --git a/apps/shared/storage_function_list_controller.h b/apps/shared/storage_function_list_controller.h index 69594078d..f1075661b 100644 --- a/apps/shared/storage_function_list_controller.h +++ b/apps/shared/storage_function_list_controller.h @@ -52,6 +52,7 @@ protected: StackViewController * stackController() const; void configureFunction(StorageFunction * function); StorageFunctionStore * m_functionStore; + SelectableTableView m_selectableTableView; private: static constexpr KDCoordinate k_minTitleColumnWidth = 65; static constexpr KDCoordinate k_functionTitleSumOfMargins = 2*Metric::HistoryHorizontalMargin; @@ -66,7 +67,6 @@ private: virtual FunctionTitleCell * titleCells(int index) = 0; virtual HighlightCell * expressionCells(int index) = 0; virtual void willDisplayTitleCellAtIndex(HighlightCell * cell, int j) = 0; - SelectableTableView m_selectableTableView; EvenOddCell m_emptyCell; Button m_plotButton; Button m_valuesButton; diff --git a/ion/include/ion/storage.h b/ion/include/ion/storage.h index 171160a98..d055282f0 100644 --- a/ion/include/ion/storage.h +++ b/ion/include/ion/storage.h @@ -53,6 +53,9 @@ public: const char * fullName() const { return Storage::sharedStorage()->fullNameOfRecord(*this); } + ErrorStatus setBaseNameWithExtension(const char * baseName, const char * extension) { + return Storage::sharedStorage()->setBaseNameWithExtensionOfRecord(*this, baseName, extension); + } ErrorStatus setName(const char * fullName) { return Storage::sharedStorage()->setFullNameOfRecord(*this, fullName); }