diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 7c84a5535..f3ee86ad3 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -44,30 +44,25 @@ TableView * EditExpressionController::ContentView::mainView() { } EditExpressionController::EditExpressionController(Responder * parentResponder, HistoryController * historyController, CalculationStore * calculationStore) : - ViewController(parentResponder), - m_contentView(this, (TableView *)historyController->view(), this), + DynamicViewController(parentResponder), m_historyController(historyController), m_calculationStore(calculationStore) { } -View * EditExpressionController::view() { - return &m_contentView; -} - const char * EditExpressionController::textBody() { - return m_contentView.textField()->text(); + return ((ContentView *)view())->textField()->text(); } void EditExpressionController::setTextBody(const char * text) { - m_contentView.textField()->setEditing(true); - m_contentView.textField()->setText(text); + ((ContentView *)view())->textField()->setEditing(true); + ((ContentView *)view())->textField()->setText(text); } bool EditExpressionController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { if (m_calculationStore->numberOfCalculations() > 0) { - m_contentView.textField()->setEditing(false, false); + ((ContentView *)view())->textField()->setEditing(false, false); app()->setFirstResponder(m_historyController); } return true; @@ -76,23 +71,25 @@ bool EditExpressionController::handleEvent(Ion::Events::Event event) { } void EditExpressionController::didBecomeFirstResponder() { - m_contentView.textField()->setEditing(true, false); - app()->setFirstResponder(m_contentView.textField()); + int lastRow = m_calculationStore->numberOfCalculations() > 0 ? m_calculationStore->numberOfCalculations()-1 : 0; + m_historyController->scrollToCell(0, lastRow); + ((ContentView *)view())->textField()->setEditing(true, false); + app()->setFirstResponder(((ContentView *)view())->textField()); } bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField, const char * text) { App * calculationApp = (App *)app(); m_calculationStore->push(textBody(), calculationApp->localContext()); m_historyController->reload(); - m_contentView.mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); - m_contentView.textField()->setEditing(true); - m_contentView.textField()->setText(""); + ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); + ((ContentView *)view())->textField()->setEditing(true); + ((ContentView *)view())->textField()->setText(""); return true; } bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField, const char * text) { - m_contentView.textField()->setEditing(true); - m_contentView.textField()->setText(text); + ((ContentView *)view())->textField()->setEditing(true); + ((ContentView *)view())->textField()->setText(text); return false; } @@ -100,4 +97,18 @@ TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() { return (App *)app(); } +void EditExpressionController::loadView() { + m_historyController->loadView(); + DynamicViewController::loadView(); +} + +void EditExpressionController::unloadView() { + m_historyController->unloadView(); + DynamicViewController::unloadView(); +} + +View * EditExpressionController::createView() { + return new ContentView(this, (TableView *)m_historyController->view(), this); +} + } diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index e652dc79d..e4b9ea151 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -10,16 +10,17 @@ namespace Calculation { class HistoryController; -class EditExpressionController : public ViewController, public Shared::TextFieldDelegate { +class EditExpressionController : public DynamicViewController, public Shared::TextFieldDelegate { public: EditExpressionController(Responder * parentResponder, HistoryController * historyController, CalculationStore * calculationStore); - View * view() override; void didBecomeFirstResponder() override; bool handleEvent(Ion::Events::Event event) override; const char * textBody(); void setTextBody(const char * text); bool textFieldDidFinishEditing(::TextField * textField, const char * text) override; bool textFieldDidAbortEditing(::TextField * textField, const char * text) override; + void loadView() override; + void unloadView() override; private: class ContentView : public View { public: @@ -37,8 +38,8 @@ private: TextField m_textField; char m_textBody[TextField::maxBufferSize()]; }; + View * createView() override; Shared::TextFieldDelegateApp * textFieldDelegateApp() override; - ContentView m_contentView; HistoryController * m_historyController; CalculationStore * m_calculationStore; }; diff --git a/apps/calculation/history_controller.cpp b/apps/calculation/history_controller.cpp index 8c2fae229..75f406c39 100644 --- a/apps/calculation/history_controller.cpp +++ b/apps/calculation/history_controller.cpp @@ -6,28 +6,23 @@ namespace Calculation { HistoryController::HistoryController(Responder * parentResponder, CalculationStore * calculationStore) : - ViewController(parentResponder), - m_selectableTableView(CalculationSelectableTableView(this, this, this)), + DynamicViewController(parentResponder), m_calculationStore(calculationStore) { } -View * HistoryController::HistoryController::view() { - return &m_selectableTableView; -} - void HistoryController::reload() { - m_selectableTableView.reloadData(); + selectableTableView()->reloadData(); } void HistoryController::didBecomeFirstResponder() { - m_selectableTableView.selectCellAtLocation(0, numberOfRows()-1); - app()->setFirstResponder(&m_selectableTableView); + selectableTableView()->selectCellAtLocation(0, numberOfRows()-1); + app()->setFirstResponder(selectableTableView()); } bool HistoryController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Down) { - m_selectableTableView.deselectTable(); + selectableTableView()->deselectTable(); app()->setFirstResponder(parentResponder()); return true; } @@ -35,11 +30,11 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { return true; } if (event == Ion::Events::OK) { - int focusRow = m_selectableTableView.selectedRow(); - HistoryViewCell * selectedCell = (HistoryViewCell *)m_selectableTableView.cellAtLocation(0, focusRow); + int focusRow = selectableTableView()->selectedRow(); + HistoryViewCell * selectedCell = (HistoryViewCell *)selectableTableView()->cellAtLocation(0, focusRow); HistoryViewCell::SubviewType subviewType = selectedCell->selectedSubviewType(); EditExpressionController * editController = (EditExpressionController *)parentResponder(); - m_selectableTableView.deselectTable(); + selectableTableView()->deselectTable(); app()->setFirstResponder(editController); Calculation * calculation = m_calculationStore->calculationAtIndex(focusRow); if (subviewType == HistoryViewCell::SubviewType::Input) { @@ -50,8 +45,8 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { return true; } if (event == Ion::Events::EXE) { - int focusRow = m_selectableTableView.selectedRow(); - HistoryViewCell * selectedCell = (HistoryViewCell *)m_selectableTableView.cellAtLocation(0, focusRow); + int focusRow = selectableTableView()->selectedRow(); + HistoryViewCell * selectedCell = (HistoryViewCell *)selectableTableView()->cellAtLocation(0, focusRow); HistoryViewCell::SubviewType subviewType = selectedCell->selectedSubviewType(); EditExpressionController * editController = (EditExpressionController *)parentResponder(); Calculation * calculation = m_calculationStore->calculationAtIndex(focusRow); @@ -61,19 +56,19 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { } else { text = calculation->outputText(); } - m_selectableTableView.deselectTable(); + selectableTableView()->deselectTable(); App * calculationApp = (App *)app(); m_calculationStore->push(text, calculationApp->localContext()); reload(); - m_selectableTableView.scrollToCell(0, numberOfRows()-1); + selectableTableView()->scrollToCell(0, numberOfRows()-1); app()->setFirstResponder(editController); return true; } if (event == Ion::Events::Backspace) { - int focusRow = m_selectableTableView.selectedRow(); - HistoryViewCell * selectedCell = (HistoryViewCell *)m_selectableTableView.cellAtLocation(0, focusRow); + int focusRow = selectableTableView()->selectedRow(); + HistoryViewCell * selectedCell = (HistoryViewCell *)selectableTableView()->cellAtLocation(0, focusRow); HistoryViewCell::SubviewType subviewType = selectedCell->selectedSubviewType(); - m_selectableTableView.deselectTable(); + selectableTableView()->deselectTable(); EditExpressionController * editController = (EditExpressionController *)parentResponder(); m_calculationStore->deleteCalculationAtIndex(focusRow); reload(); @@ -82,16 +77,16 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { return true; } if (focusRow > 0) { - m_selectableTableView.selectCellAtLocation(0, focusRow-1); + selectableTableView()->selectCellAtLocation(0, focusRow-1); } else { - m_selectableTableView.selectCellAtLocation(0, 0); + selectableTableView()->selectCellAtLocation(0, 0); } if (subviewType == HistoryViewCell::SubviewType::Input) { - tableViewDidChangeSelection(&m_selectableTableView, 0, m_selectableTableView.selectedRow()); + tableViewDidChangeSelection(selectableTableView(), 0, selectableTableView()->selectedRow()); } else { - tableViewDidChangeSelection(&m_selectableTableView, 0, -1); + tableViewDidChangeSelection(selectableTableView(), 0, -1); } - m_selectableTableView.scrollToCell(0, m_selectableTableView.selectedRow()); + selectableTableView()->scrollToCell(0, selectableTableView()->selectedRow()); return true; } if (event == Ion::Events::Clear) { @@ -102,7 +97,7 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { } if (event == Ion::Events::Back) { EditExpressionController * editController = (EditExpressionController *)parentResponder(); - m_selectableTableView.deselectTable(); + selectableTableView()->deselectTable(); app()->setFirstResponder(editController); return true; } @@ -112,10 +107,10 @@ bool HistoryController::handleEvent(Ion::Events::Event event) { void HistoryController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) { HistoryViewCell * selectedCell = (HistoryViewCell *)(t->selectedCell()); selectedCell->setParentResponder(t); - if (m_selectableTableView.selectedRow() < previousSelectedCellY) { + if (selectableTableView()->selectedRow() < previousSelectedCellY) { selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Output); } - if (m_selectableTableView.selectedRow() >= previousSelectedCellY) { + if (selectableTableView()->selectedRow() >= previousSelectedCellY) { selectedCell->setSelectedSubviewType(HistoryViewCell::SubviewType::Input); } if (previousSelectedCellY == -1) { @@ -133,7 +128,7 @@ HighlightCell * HistoryController::reusableCell(int index, int type) { assert(type == 0); assert(index >= 0); assert(index < k_maxNumberOfDisplayedRows); - return &m_calculationHistory[index]; + return m_calculationHistory[index]; } int HistoryController::reusableCellCount(int type) { @@ -175,4 +170,29 @@ int HistoryController::typeAtLocation(int i, int j) { return 0; } +void HistoryController::unloadView() { + for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { + assert(m_calculationHistory[i] != nullptr); + delete m_calculationHistory[i]; + m_calculationHistory[i] = nullptr; + } + DynamicViewController::unloadView(); +} + +void HistoryController::scrollToCell(int i, int j) { + selectableTableView()->scrollToCell(i, j); +} + +View * HistoryController::createView() { + for (int i = 0; i < k_maxNumberOfDisplayedRows; i++) { + assert(m_calculationHistory[i] == nullptr); + m_calculationHistory[i] = new HistoryViewCell(); + } + return new CalculationSelectableTableView(this, this, this); +} + +CalculationSelectableTableView * HistoryController::selectableTableView() { + return (CalculationSelectableTableView *)view(); +} + } diff --git a/apps/calculation/history_controller.h b/apps/calculation/history_controller.h index c58c992f5..f8eb24bf5 100644 --- a/apps/calculation/history_controller.h +++ b/apps/calculation/history_controller.h @@ -11,11 +11,10 @@ namespace Calculation { class App; -class HistoryController : public ViewController, public ListViewDataSource, public SelectableTableViewDelegate { +class HistoryController : public DynamicViewController, public ListViewDataSource, public SelectableTableViewDelegate { public: HistoryController(Responder * parentResponder, CalculationStore * calculationStore); - View * view() override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; void reload(); @@ -28,10 +27,13 @@ public: int indexFromCumulatedHeight(KDCoordinate offsetY) override; int typeAtLocation(int i, int j) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; + void unloadView() override; + void scrollToCell(int i, int j); private: + View * createView() override; + CalculationSelectableTableView * selectableTableView(); constexpr static int k_maxNumberOfDisplayedRows = 5; - HistoryViewCell m_calculationHistory[k_maxNumberOfDisplayedRows]; - CalculationSelectableTableView m_selectableTableView; + HistoryViewCell * m_calculationHistory[k_maxNumberOfDisplayedRows]; CalculationStore * m_calculationStore; }; diff --git a/apps/calculation/selectable_table_view.cpp b/apps/calculation/selectable_table_view.cpp index 12aa4c661..5103e1e9c 100644 --- a/apps/calculation/selectable_table_view.cpp +++ b/apps/calculation/selectable_table_view.cpp @@ -21,7 +21,7 @@ void CalculationSelectableTableView::scrollToCell(int i, int j) { KDCoordinate contentOffsetY = dataSource()->cumulatedHeightFromIndex(dataSource()->numberOfRows()) - maxContentHeightDisplayableWithoutScrolling(); setContentOffset(KDPoint(contentOffsetX, contentOffsetY)); } - if (dataSource()->rowHeight(j) > bounds().height()) { + if (dataSource()->numberOfRows() > j && dataSource()->numberOfColumns() > i && dataSource()->rowHeight(j) > bounds().height()) { KDCoordinate contentOffsetX = contentOffset().x(); KDCoordinate contentOffsetY = contentOffset().y(); if (contentOffsetY > dataSource()->cumulatedHeightFromIndex(j) && contentOffsetY > dataSource()->cumulatedHeightFromIndex(j+1)) {