[solver] Make Solver::ListController inherits from

StorageExpressionModelListController instead of
ExpressionModelListController
This commit is contained in:
Émilie Feral
2019-02-22 16:25:29 +01:00
parent d6f5f1bbea
commit 2ba077af28
9 changed files with 90 additions and 81 deletions

View File

@@ -4,6 +4,8 @@
namespace Shared {
static inline int minInt(int x, int y) { return x < y ? x : y; }
/* Table Data Source */
StorageExpressionModelListController::StorageExpressionModelListController(Responder * parentResponder, I18n::Message text) :
@@ -50,7 +52,7 @@ KDCoordinate StorageExpressionModelListController::memoizedRowHeight(int j) {
if (j < 0) {
return 0;
}
int currentSelectedRow = selectedRow();
int currentSelectedRow = selectedRow() < 0 ? 0 : selectedRow();
constexpr int halfMemoizationCount = k_memoizedCellsCount/2;
if (j >= currentSelectedRow - halfMemoizationCount && j <= currentSelectedRow + halfMemoizationCount) {
int memoizedIndex = j - (currentSelectedRow - halfMemoizationCount);
@@ -66,7 +68,7 @@ KDCoordinate StorageExpressionModelListController::memoizedCumulatedHeightFromIn
if (j <= 0) {
return 0;
}
int currentSelectedRow = selectedRow();
int currentSelectedRow = selectedRow() < 0 ? 0 : selectedRow();
constexpr int halfMemoizationCount = k_memoizedCellsCount/2;
/* If j is not easily computable from the memoized values, compute it the hard
* way. */
@@ -97,7 +99,45 @@ KDCoordinate StorageExpressionModelListController::memoizedCumulatedHeightFromIn
return result;
}
int StorageExpressionModelListController::memoizedIndexFromCumulatedHeight(KDCoordinate offsetY) {
if (offsetY == 0) {
return 0;
}
/* We use memoization to speed up this method: if offsetY is "around" the
* memoized cumulatedHeightForIndex, we can compute its value easily by
* adding/substracting memoized row heights. */
int currentSelectedRow = selectedRow() < 0 ? 0 : selectedRow();
int rowsCount = numberOfExpressionRows();
if (rowsCount <= 1 || currentSelectedRow < 1) {
return notMemoizedIndexFromCumulatedHeight(offsetY);
}
KDCoordinate currentCumulatedHeight = memoizedCumulatedHeightFromIndex(currentSelectedRow);
if (offsetY > currentCumulatedHeight) {
int iMax = minInt(k_memoizedCellsCount/2 + 1, rowsCount - currentSelectedRow);
for (int i = 0; i < iMax; i++) {
currentCumulatedHeight+= memoizedRowHeight(currentSelectedRow + i);
if (offsetY <= currentCumulatedHeight) {
return currentSelectedRow + i;
}
}
} else {
int iMax = minInt(k_memoizedCellsCount/2, currentSelectedRow);
for (int i = 1; i <= iMax; i++) {
currentCumulatedHeight-= memoizedRowHeight(currentSelectedRow-i);
if (offsetY > currentCumulatedHeight) {
return currentSelectedRow - i;
}
}
}
return notMemoizedIndexFromCumulatedHeight(offsetY);
}
int StorageExpressionModelListController::numberOfExpressionRows() {
if (modelStore()->numberOfModels() == modelStore()->maxNumberOfModels()) {
return modelStore()->numberOfModels();
}
return 1 + modelStore()->numberOfModels();
}
@@ -195,8 +235,6 @@ void StorageExpressionModelListController::editExpression(Ion::Events::Event eve
StorageExpressionModelListController * myController = static_cast<StorageExpressionModelListController *>(context);
InputViewController * myInputViewController = (InputViewController *)sender;
const char * textBody = myInputViewController->textBody();
// Reset memoization of the selected cell which always corresponds to the k_memoizedCellsCount/2 memoized cell
myController->resetMemoizationForIndex(k_memoizedCellsCount/2);
return myController->editSelectedRecordWithText(textBody);
},
[](void * context, void * sender){
@@ -205,6 +243,8 @@ void StorageExpressionModelListController::editExpression(Ion::Events::Event eve
}
bool StorageExpressionModelListController::editSelectedRecordWithText(const char * text) {
// Reset memoization of the selected cell which always corresponds to the k_memoizedCellsCount/2 memoized cell
resetMemoizationForIndex(k_memoizedCellsCount/2);
Ion::Storage::Record record = modelStore()->recordAtIndex(modelIndexForRow(selectedRow()));
ExpiringPointer<ExpressionModelHandle> model = modelStore()->modelForRecord(record);
return (model->setContent(text) == Ion::Storage::Record::ErrorStatus::None);

View File

@@ -35,8 +35,6 @@ protected:
virtual SelectableTableView * selectableTableView() = 0;
virtual StorageExpressionModelStore * modelStore() = 0;
virtual InputViewController * inputController() = 0;
EvenOddMessageTextCell m_addNewModel;
protected:
// Memoization
static constexpr int k_memoizedCellsCount = 7;
/* We use memoization to speed up indexFromHeight(offset) in the children
@@ -57,11 +55,14 @@ protected:
* || j > selectedRow + halfMemoizationCount) { ... } */
virtual void resetMemoizationForIndex(int index);
virtual void shiftMemoization(bool newCellIsUnder);
EvenOddMessageTextCell m_addNewModel;
private:
// Memoization
static constexpr int k_resetedMemoizedValue = -1;
void resetMemoization();
// TableViewDataSource
virtual KDCoordinate notMemoizedCumulatedHeightFromIndex(int j) = 0;
virtual int notMemoizedIndexFromCumulatedHeight(KDCoordinate offsetY) = 0;
KDCoordinate m_memoizedCellHeight[k_memoizedCellsCount];
KDCoordinate m_cumulatedHeightForSelectedIndex;
};

View File

@@ -41,14 +41,6 @@ void StorageFunctionListController::viewWillAppear() {
computeTitlesColumnWidth();
}
KDCoordinate StorageFunctionListController::rowHeight(int j) {
return StorageExpressionModelListController::memoizedRowHeight(j);
}
KDCoordinate StorageFunctionListController::cumulatedHeightFromIndex(int j) {
return StorageExpressionModelListController::memoizedCumulatedHeightFromIndex(j);
}
KDCoordinate StorageFunctionListController::columnWidth(int i) {
switch (i) {
case 0:
@@ -87,42 +79,6 @@ int StorageFunctionListController::indexFromCumulatedWidth(KDCoordinate offsetX)
}
}
int StorageFunctionListController::indexFromCumulatedHeight(KDCoordinate offsetY) {
if (offsetY == 0) {
return 0;
}
/* We use memoization to speed up this method: if offsetY is "around" the
* memoized cumulatedHeightForIndex, we can compute its value easily by
* adding/substracting memoized row heights. */
int currentSelectedRow = selectedRow();
int rowsCount = numberOfRows();
if (rowsCount <= 1 || currentSelectedRow < 1) {
return TableViewDataSource::indexFromCumulatedHeight(offsetY);
}
KDCoordinate currentCumulatedHeight = cumulatedHeightFromIndex(currentSelectedRow);
if (offsetY > currentCumulatedHeight) {
int iMax = minInt(k_memoizedCellsCount/2 + 1, rowsCount - currentSelectedRow);
for (int i = 0; i < iMax; i++) {
currentCumulatedHeight+= rowHeight(currentSelectedRow + i);
if (offsetY <= currentCumulatedHeight) {
return currentSelectedRow + i;
}
}
} else {
int iMax = minInt(k_memoizedCellsCount/2, currentSelectedRow);
for (int i = 1; i <= iMax; i++) {
currentCumulatedHeight-= rowHeight(currentSelectedRow-i);
if (offsetY > currentCumulatedHeight) {
return currentSelectedRow - i;
}
}
}
return TableViewDataSource::indexFromCumulatedHeight(offsetY);
}
int StorageFunctionListController::typeAtLocation(int i, int j) {
if (isAddEmptyRow(j)){
return i + 2;
@@ -320,10 +276,6 @@ void StorageFunctionListController::didChangeModelsList() {
computeTitlesColumnWidth();
}
KDCoordinate StorageFunctionListController::notMemoizedCumulatedHeightFromIndex(int j) {
return TableViewDataSource::cumulatedHeightFromIndex(j);
}
KDCoordinate StorageFunctionListController::baseline(int j) {
if (j < 0) {
return -1;

View File

@@ -20,13 +20,13 @@ public:
/* TableViewDataSource */
int numberOfRows() override { return this->numberOfExpressionRows(); }
KDCoordinate rowHeight(int j) override { return StorageExpressionModelListController::memoizedRowHeight(j); }
KDCoordinate cumulatedHeightFromIndex(int j) override { return StorageExpressionModelListController::memoizedCumulatedHeightFromIndex(j); }
int indexFromCumulatedHeight(KDCoordinate offsetY) override { return StorageExpressionModelListController::memoizedIndexFromCumulatedHeight(offsetY); }
int numberOfColumns() override { return 2; }
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;
HighlightCell * reusableCell(int index, int type) override;
int reusableCellCount(int type) override;
@@ -66,7 +66,12 @@ private:
InputViewController * inputController() override;
KDCoordinate maxFunctionNameWidth();
void didChangeModelsList() override;
KDCoordinate notMemoizedCumulatedHeightFromIndex(int j) override;
KDCoordinate notMemoizedCumulatedHeightFromIndex(int j) override {
return TableViewDataSource::cumulatedHeightFromIndex(j);
}
int notMemoizedIndexFromCumulatedHeight(KDCoordinate offsetY) override {
return TableViewDataSource::indexFromCumulatedHeight(offsetY);
}
virtual StorageListParameterController * parameterController() = 0;
virtual int maxNumberOfDisplayableRows() = 0;
virtual FunctionTitleCell * titleCells(int index) = 0;

View File

@@ -1,21 +1,22 @@
#include "equation_list_view.h"
#include "list_controller.h"
namespace Solver {
/* EquationListView */
EquationListView::EquationListView(Responder * parentResponder, TableViewDataSource * dataSource, SelectableTableViewDataSource * selectionDataSource) :
Responder(parentResponder),
EquationListView::EquationListView(ListController * listController) :
Responder(listController),
View(),
m_braceStyle(BraceStyle::None),
m_listView(this, dataSource, selectionDataSource),
m_listView(this, listController, listController, listController),
m_braceView(),
m_scrollBraceView(&m_braceView, this)
{
m_listView.setMargins(0);
m_listView.setVerticalCellOverlap(0);
m_listView.setDecoratorType(ScrollView::Decorator::Type::None);
selectionDataSource->setScrollViewDelegate(this);
listController->setScrollViewDelegate(this);
m_scrollBraceView.setMargins(k_margin, k_margin, k_margin, k_margin);
m_scrollBraceView.setDecoratorType(ScrollView::Decorator::Type::None);
m_scrollBraceView.setBackgroundColor(KDColorWhite);

View File

@@ -5,6 +5,8 @@
namespace Solver {
class ListController;
class EquationListView : public Responder, public View, public ScrollViewDelegate, public ScrollViewDataSource {
public:
enum class BraceStyle {
@@ -12,7 +14,7 @@ public:
OneRowShort,
Full
};
EquationListView(Responder * parentResponder, TableViewDataSource * dataSource, SelectableTableViewDataSource * selectionDataSource);
EquationListView(ListController * listController);
void setBraceStyle(BraceStyle style);
void scrollViewDidChangeOffset(ScrollViewDataSource * scrollViewDataSource) override;
void didBecomeFirstResponder() override;

View File

@@ -47,10 +47,14 @@ void EquationModelsParameterController::didBecomeFirstResponder() {
bool EquationModelsParameterController::handleEvent(Ion::Events::Event event) {
if (event == Ion::Events::OK || event == Ion::Events::EXE) {
Equation * newEquation = static_cast<Equation *>(m_equationStore->addEmptyModel());
newEquation->setContent(k_models[selectedRow()]);
Ion::Storage::Record::ErrorStatus error = m_equationStore->addEmptyModel();
if (error == Ion::Storage::Record::ErrorStatus::NotEnoughSpaceAvailable) {
return false;
}
assert(error == Ion::Storage::Record::ErrorStatus::None);
m_listController->editSelectedRecordWithText(k_models[selectedRow()]);
app()->dismissModalViewController();
m_listController->editExpression(newEquation, Ion::Events::OK);
m_listController->editExpression(Ion::Events::OK);
return true;
}
return false;

View File

@@ -8,10 +8,10 @@ using namespace Shared;
namespace Solver {
ListController::ListController(Responder * parentResponder, EquationStore * equationStore, ButtonRowController * footer) :
ExpressionModelListController(parentResponder, I18n::Message::AddEquation),
StorageExpressionModelListController(parentResponder, I18n::Message::AddEquation),
ButtonRowDelegate(nullptr, footer),
m_equationStore(equationStore),
m_equationListView(this, this, this),
m_equationListView(this),
m_expressionCells{},
m_resolveButton(this, equationStore->numberOfDefinedModels() > 1 ? I18n::Message::ResolveSystem : I18n::Message::ResolveEquation, Invocation([](void * context, void * sender) {
ListController * list = (ListController *)context;
@@ -214,8 +214,8 @@ void ListController::addEmptyModel() {
app()->displayModalViewController(&m_modelsStackController, 0.f, 0.f, Metric::CommonTopMargin, Metric::CommonRightMargin, 0, Metric::CommonLeftMargin);
}
bool ListController::removeModelRow(ExpressionModel * model) {
ExpressionModelListController::removeModelRow(model);
bool ListController::removeModelRow(Ion::Storage::Record record) {
StorageExpressionModelListController::removeModelRow(record);
reloadButtonMessage();
reloadBrace();
return true;

View File

@@ -2,7 +2,7 @@
#define SOLVER_LIST_CONTROLLER_H
#include <escher.h>
#include "../shared/expression_model_list_controller.h"
#include "../shared/storage_expression_model_list_controller.h"
#include "../shared/layout_field_delegate.h"
#include "../shared/text_field_delegate.h"
#include "equation_store.h"
@@ -12,19 +12,17 @@
namespace Solver {
class ListController : public Shared::ExpressionModelListController, public ButtonRowDelegate, public ListViewDataSource, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
class ListController : public Shared::StorageExpressionModelListController, public ButtonRowDelegate, public ListViewDataSource, public Shared::TextFieldDelegate, public Shared::LayoutFieldDelegate {
public:
ListController(Responder * parentResponder, EquationStore * equationStore, ButtonRowController * footer);
/* ButtonRowDelegate */
int numberOfButtons(ButtonRowController::Position position) const override;
Button * buttonAtIndex(int index, ButtonRowController::Position position) const override;
/* ListViewDataSource */
int numberOfRows() override {
return numberOfExpressionRows();
}
KDCoordinate rowHeight(int j) override {
return expressionRowHeight(j);
}
int numberOfRows() override { return numberOfExpressionRows(); }
KDCoordinate rowHeight(int j) override{ return StorageExpressionModelListController::memoizedRowHeight(j); }
KDCoordinate cumulatedHeightFromIndex(int j) override { return StorageExpressionModelListController::memoizedCumulatedHeightFromIndex(j); }
int indexFromCumulatedHeight(KDCoordinate offsetY) override { return StorageExpressionModelListController::memoizedIndexFromCumulatedHeight(offsetY); }
int typeAtLocation(int i, int j) override;
HighlightCell * reusableCell(int index, int type) override;
int reusableCellCount(int type) override;
@@ -33,7 +31,10 @@ public:
bool handleEvent(Ion::Events::Event event) override;
void didBecomeFirstResponder() override;
void didEnterResponderChain(Responder * previousFirstResponder) override;
void editExpression(Shared::ExpressionModel * model, Ion::Events::Event event) override { return Shared::ExpressionModelListController::editExpression(model, event); }
/* StorageExpressionModelListController */
// Make methods public
void editExpression(Ion::Events::Event event) override { return Shared::StorageExpressionModelListController::editExpression(event); }
bool editSelectedRecordWithText(const char * text) override { return Shared::StorageExpressionModelListController::editSelectedRecordWithText(text); }
/* ViewController */
View * view() override { return &m_equationListView; }
/* Text/Layout Field Delegate */
@@ -50,11 +51,14 @@ private:
SelectableTableView * selectableTableView() override;
void reloadButtonMessage();
void addEmptyModel() override;
bool removeModelRow(Shared::ExpressionModel * function) override;
bool removeModelRow(Ion::Storage::Record record) override;
void reloadBrace();
Shared::ExpressionModelStore * modelStore() override { return m_equationStore; }
Shared::StorageExpressionModelStore * modelStore() override { return m_equationStore; }
StackViewController * stackController() const;
InputViewController * inputController() override;
// ListViewDataSource
KDCoordinate notMemoizedCumulatedHeightFromIndex(int j) override { return ListViewDataSource::cumulatedHeightFromIndex(j); }
int notMemoizedIndexFromCumulatedHeight(KDCoordinate offsetY) override { return ListViewDataSource::indexFromCumulatedHeight(offsetY); }
EquationStore * m_equationStore;
EquationListView m_equationListView;
EvenOddExpressionCell m_expressionCells[k_maxNumberOfRows];