diff --git a/apps/battery_view.cpp b/apps/battery_view.cpp index 075b3f4ae..706407a22 100644 --- a/apps/battery_view.cpp +++ b/apps/battery_view.cpp @@ -32,6 +32,6 @@ void BatteryView::drawRect(KDContext * ctx, KDRect rect) const { ctx->fillRect(KDRect(k_batteryWidth-k_elementWidth, (k_batteryHeight-k_capHeight)/2, k_elementWidth, k_capHeight), KDColorWhite); } -KDSize BatteryView::minimalSizeForOptimalDisplay() { +KDSize BatteryView::minimalSizeForOptimalDisplay() const { return KDSize(k_batteryWidth, k_batteryHeight); } diff --git a/apps/battery_view.h b/apps/battery_view.h index 52e5aa489..99fefd37f 100644 --- a/apps/battery_view.h +++ b/apps/battery_view.h @@ -8,7 +8,7 @@ public: BatteryView(); void setChargeState(Ion::Battery::Charge chargeState); void drawRect(KDContext * ctx, KDRect rect) const override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: constexpr static KDCoordinate k_batteryHeight = 8; constexpr static KDCoordinate k_batteryWidth = 13; diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index bcc98cbc0..1825e03f5 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -60,12 +60,14 @@ const char * EditExpressionController::textBody() { } void EditExpressionController::setTextBody(const char * text) { + m_contentView.textField()->setEditing(true); m_contentView.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); app()->setFirstResponder(m_historyController); } return true; @@ -74,6 +76,7 @@ bool EditExpressionController::handleEvent(Ion::Events::Event event) { } void EditExpressionController::didBecomeFirstResponder() { + m_contentView.textField()->setEditing(true); app()->setFirstResponder(m_contentView.textField()); } @@ -82,10 +85,17 @@ bool EditExpressionController::textFieldDidFinishEditing(::TextField * textField 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(""); return true; } +bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField, const char * text) { + m_contentView.textField()->setEditing(true); + m_contentView.textField()->setText(text); + return false; +} + TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() { return (App *)app(); } diff --git a/apps/calculation/edit_expression_controller.h b/apps/calculation/edit_expression_controller.h index ca1632587..42a0e734f 100644 --- a/apps/calculation/edit_expression_controller.h +++ b/apps/calculation/edit_expression_controller.h @@ -20,6 +20,7 @@ public: const char * textBody(); void setTextBody(const char * text); bool textFieldDidFinishEditing(::TextField * textField, const char * text) override; + bool textFieldDidAbortEditing(::TextField * textField, const char * text) override; private: class ContentView : public View { public: diff --git a/apps/calculation/scrollable_expression_view.cpp b/apps/calculation/scrollable_expression_view.cpp index 599805971..5607612dd 100644 --- a/apps/calculation/scrollable_expression_view.cpp +++ b/apps/calculation/scrollable_expression_view.cpp @@ -19,7 +19,7 @@ void ScrollableExpressionView::setBackgroundColor(KDColor backgroundColor) { m_expressionView.setBackgroundColor(backgroundColor); } -KDSize ScrollableExpressionView::minimalSizeForOptimalDisplay() { +KDSize ScrollableExpressionView::minimalSizeForOptimalDisplay() const { return m_expressionView.minimalSizeForOptimalDisplay(); } diff --git a/apps/calculation/scrollable_expression_view.h b/apps/calculation/scrollable_expression_view.h index 7ee211e0d..d59adc7b7 100644 --- a/apps/calculation/scrollable_expression_view.h +++ b/apps/calculation/scrollable_expression_view.h @@ -10,7 +10,7 @@ public: ScrollableExpressionView(Responder * parentResponder); void setExpression(Poincare::ExpressionLayout * expressionLayout); void setBackgroundColor(KDColor backgroundColor); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: View * view() override; ExpressionView m_expressionView; diff --git a/apps/calculation/text_field.cpp b/apps/calculation/text_field.cpp index 033b94e44..5c364369f 100644 --- a/apps/calculation/text_field.cpp +++ b/apps/calculation/text_field.cpp @@ -31,8 +31,4 @@ bool TextField::handleEvent(Ion::Events::Event event) { return(::TextField::handleEvent(event)); } -void TextField::setEditing(bool isEditing) { - ::TextField::setEditing(true); -} - } diff --git a/apps/calculation/text_field.h b/apps/calculation/text_field.h index 99d11b898..6d2f12392 100644 --- a/apps/calculation/text_field.h +++ b/apps/calculation/text_field.h @@ -9,7 +9,6 @@ class TextField : public ::TextField { public: TextField(Responder * parentResponder, char * textBuffer, size_t textBufferSize, TextFieldDelegate * delegate); bool handleEvent(Ion::Events::Event event) override; - void setEditing(bool isEditing) override; }; } diff --git a/apps/graph/graph/banner_view.cpp b/apps/graph/graph/banner_view.cpp index 331db9705..c57f3f79d 100644 --- a/apps/graph/graph/banner_view.cpp +++ b/apps/graph/graph/banner_view.cpp @@ -25,9 +25,9 @@ int BannerView::numberOfSubviews() const { return 2; } -TextView * BannerView::textViewAtIndex(int i) { - TextView * textViews[3] = {&m_abscissaView, &m_functionView, &m_derivativeView}; - return textViews[i]; +TextView * BannerView::textViewAtIndex(int i) const { + const TextView * textViews[3] = {&m_abscissaView, &m_functionView, &m_derivativeView}; + return (TextView *)textViews[i]; } } diff --git a/apps/graph/graph/banner_view.h b/apps/graph/graph/banner_view.h index ac3310f89..c2b3bf191 100644 --- a/apps/graph/graph/banner_view.h +++ b/apps/graph/graph/banner_view.h @@ -12,7 +12,7 @@ public: bool displayDerivative(); private: int numberOfSubviews() const override; - TextView * textViewAtIndex(int i) override; + TextView * textViewAtIndex(int i) const override; BufferTextView m_abscissaView; BufferTextView m_functionView; BufferTextView m_derivativeView; diff --git a/apps/regression/banner_view.cpp b/apps/regression/banner_view.cpp index 2f1cb3a54..8b13324cd 100644 --- a/apps/regression/banner_view.cpp +++ b/apps/regression/banner_view.cpp @@ -15,9 +15,9 @@ int BannerView::numberOfSubviews() const { return 5; } -TextView * BannerView::textViewAtIndex(int i) { - TextView * textViews[5] = {&m_regressionTypeView, &m_slopeView, &m_yInterceptView, &m_xView, &m_yView}; - return textViews[i]; +TextView * BannerView::textViewAtIndex(int i) const { + const TextView * textViews[5] = {&m_regressionTypeView, &m_slopeView, &m_yInterceptView, &m_xView, &m_yView}; + return (TextView *)textViews[i]; } } diff --git a/apps/regression/banner_view.h b/apps/regression/banner_view.h index 1046125d2..4a03c82cd 100644 --- a/apps/regression/banner_view.h +++ b/apps/regression/banner_view.h @@ -11,7 +11,7 @@ public: BannerView(); private: int numberOfSubviews() const override; - TextView * textViewAtIndex(int i) override; + TextView * textViewAtIndex(int i) const override; PointerTextView m_regressionTypeView; BufferTextView m_slopeView; BufferTextView m_yInterceptView; diff --git a/apps/regression/calculation_controller.cpp b/apps/regression/calculation_controller.cpp index a6d457508..e18578df8 100644 --- a/apps/regression/calculation_controller.cpp +++ b/apps/regression/calculation_controller.cpp @@ -7,19 +7,18 @@ #include using namespace Poincare; +using namespace Shared; namespace Regression { CalculationController::CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store) : - ViewController(parentResponder), + TabTableController(parentResponder, Metric::CommonTopMargin, Metric::CommonRightMargin, Metric::CommonBottomMargin, Metric::CommonLeftMargin, this, true), ButtonRowDelegate(header, nullptr), m_titleCells{EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small)}, m_r2TitleCell(1.0f, 0.5f), m_columnTitleCell(EvenOddDoubleBufferTextCell(&m_selectableTableView)), m_calculationCells{EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small)}, - m_selectableTableView(SelectableTableView(this, this, Metric::CommonTopMargin, Metric::CommonRightMargin, - Metric::CommonBottomMargin, Metric::CommonLeftMargin, this, true, true, Palette::WallScreenDark)), m_store(store) { for (int k = 0; k < k_maxNumberOfDisplayableRows/2; k++) { @@ -41,10 +40,6 @@ const char * CalculationController::title() const { return "Statistiques"; } -View * CalculationController::view() { - return &m_selectableTableView; -} - bool CalculationController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { m_selectableTableView.deselectTable(); @@ -60,7 +55,7 @@ void CalculationController::didBecomeFirstResponder() { } else { m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); } - app()->setFirstResponder(&m_selectableTableView); + TabTableController::didBecomeFirstResponder(); } void CalculationController::tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) { @@ -181,22 +176,6 @@ KDCoordinate CalculationController::rowHeight(int j) { return k_cellHeight; } -KDCoordinate CalculationController::cumulatedWidthFromIndex(int i) { - return i*k_cellWidth; -} - -KDCoordinate CalculationController::cumulatedHeightFromIndex(int j) { - return j*k_cellHeight; -} - -int CalculationController::indexFromCumulatedWidth(KDCoordinate offsetX) { - return (offsetX-1) / k_cellWidth; -} - -int CalculationController::indexFromCumulatedHeight(KDCoordinate offsetY) { - return (offsetY-1) / k_cellHeight; -} - HighlightCell * CalculationController::reusableCell(int index, int type) { if (type == 0) { assert(index < k_maxNumberOfDisplayableRows); @@ -250,16 +229,6 @@ int CalculationController::typeAtLocation(int i, int j) { return 4; } -void CalculationController::viewWillAppear() { - m_selectableTableView.reloadData(); -} - -void CalculationController::willExitResponderChain(Responder * nextFirstResponder) { - if (nextFirstResponder == tabController()) { - m_selectableTableView.deselectTable(); - } -} - Responder * CalculationController::tabController() const { return (parentResponder()->parentResponder()->parentResponder()); } diff --git a/apps/regression/calculation_controller.h b/apps/regression/calculation_controller.h index 477ffa3cf..d98f1fa88 100644 --- a/apps/regression/calculation_controller.h +++ b/apps/regression/calculation_controller.h @@ -4,16 +4,16 @@ #include #include "store.h" #include "even_odd_double_buffer_text_cell.h" +#include "../shared/tab_table_controller.h" namespace Regression { -class CalculationController : public ViewController, public ButtonRowDelegate, public AlternateEmptyViewDelegate, public TableViewDataSource, public SelectableTableViewDelegate { +class CalculationController : public Shared::TabTableController, public ButtonRowDelegate, public AlternateEmptyViewDelegate, public SelectableTableViewDelegate { public: CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store); ~CalculationController(); const char * title() const override; - View * view() override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; @@ -27,17 +27,11 @@ public: void willDisplayCellAtLocation(HighlightCell * 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; HighlightCell * reusableCell(int index, int type) override; int reusableCellCount(int type) override; int typeAtLocation(int i, int j) override; - void viewWillAppear() override; - void willExitResponderChain(Responder * nextFirstResponder) override; private: - Responder * tabController() const; + Responder * tabController() const override; constexpr static int k_totalNumberOfRows = 11; constexpr static int k_totalNumberOfColumns = 2; constexpr static int k_maxNumberOfDisplayableRows = 10; @@ -49,7 +43,6 @@ private: EvenOddDoubleBufferTextCell m_columnTitleCell; EvenOddDoubleBufferTextCell m_doubleCalculationCells[k_maxNumberOfDisplayableRows/2]; EvenOddBufferTextCell m_calculationCells[k_maxNumberOfDisplayableRows/2]; - SelectableTableView m_selectableTableView; Store * m_store; }; diff --git a/apps/sequence/graph/banner_view.cpp b/apps/sequence/graph/banner_view.cpp index 47e223664..0a5f0e920 100644 --- a/apps/sequence/graph/banner_view.cpp +++ b/apps/sequence/graph/banner_view.cpp @@ -12,9 +12,9 @@ int BannerView::numberOfSubviews() const { return 2; } -TextView * BannerView::textViewAtIndex(int i) { - TextView * views[2] = {&m_abscissaView, &m_sequenceView}; - return views[i]; +TextView * BannerView::textViewAtIndex(int i) const { + const TextView * views[2] = {&m_abscissaView, &m_sequenceView}; + return (TextView *)views[i]; } } diff --git a/apps/sequence/graph/banner_view.h b/apps/sequence/graph/banner_view.h index e855f9a36..4d2727e7f 100644 --- a/apps/sequence/graph/banner_view.h +++ b/apps/sequence/graph/banner_view.h @@ -11,7 +11,7 @@ public: BannerView(); private: int numberOfSubviews() const override; - TextView * textViewAtIndex(int i) override; + TextView * textViewAtIndex(int i) const override; BufferTextView m_abscissaView; BufferTextView m_sequenceView; }; diff --git a/apps/sequence/graph/term_sum_controller.cpp b/apps/sequence/graph/term_sum_controller.cpp index 92f6b7a6a..6e1e0770a 100644 --- a/apps/sequence/graph/term_sum_controller.cpp +++ b/apps/sequence/graph/term_sum_controller.cpp @@ -108,6 +108,7 @@ bool TermSumController::handleEvent(Ion::Events::Event event) { m_contentView.graphView()->setHighlightColor(true); m_contentView.graphView()->selectMainView(false); m_contentView.legendView()->setLegendText(buffer); + return true; } return false; } diff --git a/apps/settings/main_controller.cpp b/apps/settings/main_controller.cpp index 5766be51e..f66f9e9b4 100644 --- a/apps/settings/main_controller.cpp +++ b/apps/settings/main_controller.cpp @@ -56,6 +56,7 @@ bool MainController::handleEvent(Ion::Events::Event event) { m_subController.setNodeModel(m_nodeModel->children(m_selectableTableView.selectedRow()), m_selectableTableView.selectedRow()); StackViewController * stack = stackController(); stack->push(&m_subController); + return true; } return false; } diff --git a/apps/settings/sub_controller.cpp b/apps/settings/sub_controller.cpp index 995569eb6..5ca8a27fe 100644 --- a/apps/settings/sub_controller.cpp +++ b/apps/settings/sub_controller.cpp @@ -60,6 +60,7 @@ bool SubController::handleEvent(Ion::Events::Event event) { myContainer->refreshPreferences(); StackViewController * stack = stackController(); stack->pop(); + return true; } return false; } diff --git a/apps/shared/Makefile b/apps/shared/Makefile index 69ff00d24..34ad1cc5b 100644 --- a/apps/shared/Makefile +++ b/apps/shared/Makefile @@ -28,6 +28,7 @@ app_objs += $(addprefix apps/shared/,\ range_parameter_controller.o\ store_controller.o\ store_parameter_controller.o\ + tab_table_controller.o\ text_field_delegate.o\ text_field_delegate_app.o\ values_function_parameter_controller.o\ diff --git a/apps/shared/banner_view.cpp b/apps/shared/banner_view.cpp index c3c8fdb3e..6830c482e 100644 --- a/apps/shared/banner_view.cpp +++ b/apps/shared/banner_view.cpp @@ -15,7 +15,7 @@ void BannerView::setLegendAtIndex(char * text, int index) { layoutSubviews(); } -KDSize BannerView::minimalSizeForOptimalDisplay() { +KDSize BannerView::minimalSizeForOptimalDisplay() const { return KDSize(0, KDText::stringSize(" ", KDText::FontSize::Small).height()*numberOfLines()); } @@ -70,7 +70,7 @@ View * BannerView::subviewAtIndex(int index) { return textViewAtIndex(index); } -int BannerView::numberOfLines() { +int BannerView::numberOfLines() const { KDCoordinate width = bounds().width(); KDCoordinate usedWidth = 0; KDCoordinate lineNumber = 0; diff --git a/apps/shared/banner_view.h b/apps/shared/banner_view.h index 093197f77..c51d3b276 100644 --- a/apps/shared/banner_view.h +++ b/apps/shared/banner_view.h @@ -8,13 +8,13 @@ namespace Shared { class BannerView : public View { public: void setLegendAtIndex(char * text, int index); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: int numberOfSubviews() const override; View * subviewAtIndex(int index) override; void layoutSubviews() override; - int numberOfLines(); - virtual TextView * textViewAtIndex(int i) = 0; + int numberOfLines() const; + virtual TextView * textViewAtIndex(int i) const = 0; }; } diff --git a/apps/shared/editable_cell_table_view_controller.cpp b/apps/shared/editable_cell_table_view_controller.cpp index 78d25f39e..417f88755 100644 --- a/apps/shared/editable_cell_table_view_controller.cpp +++ b/apps/shared/editable_cell_table_view_controller.cpp @@ -10,16 +10,10 @@ namespace Shared { EditableCellTableViewController::EditableCellTableViewController(Responder * parentResponder, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin) : - ViewController(parentResponder), - m_selectableTableView(SelectableTableView(this, this, topMargin, rightMargin, bottomMargin, leftMargin, this, - false, true, Palette::WallScreenDark)) + TabTableController(parentResponder, topMargin, rightMargin, bottomMargin, leftMargin, this, true) { } -View * EditableCellTableViewController::view() { - return &m_selectableTableView; -} - bool EditableCellTableViewController::textFieldDidFinishEditing(TextField * textField, const char * text) { AppsContainer * appsContainer = ((TextFieldDelegateApp *)app())->container(); Context * globalContext = appsContainer->globalContext(); @@ -64,14 +58,6 @@ 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::willDisplayCellAtLocationWithDisplayMode(HighlightCell * cell, int i, int j, Expression::FloatDisplayMode floatDisplayMode) { EvenOddCell * myCell = (EvenOddCell *)cell; myCell->setEven(j%2 == 0); @@ -104,12 +90,12 @@ void EditableCellTableViewController::didBecomeFirstResponder() { int selectedColumn = m_selectableTableView.selectedColumn(); selectedColumn = selectedColumn >= numberOfColumns() ? numberOfColumns() - 1 : selectedColumn; m_selectableTableView.selectCellAtLocation(selectedColumn, selectedRow); - app()->setFirstResponder(&m_selectableTableView); + TabTableController::didBecomeFirstResponder(); } } void EditableCellTableViewController::viewWillAppear() { - m_selectableTableView.reloadData(); + TabTableController::viewWillAppear(); if (m_selectableTableView.selectedRow() == -1) { m_selectableTableView.selectCellAtLocation(0, 1); } else { @@ -121,12 +107,6 @@ void EditableCellTableViewController::viewWillAppear() { } } -void EditableCellTableViewController::willExitResponderChain(Responder * nextFirstResponder) { - if (nextFirstResponder == tabController()) { - m_selectableTableView.deselectTable(); - } -} - TextFieldDelegateApp * EditableCellTableViewController::textFieldDelegateApp() { return (TextFieldDelegateApp *)app(); } diff --git a/apps/shared/editable_cell_table_view_controller.h b/apps/shared/editable_cell_table_view_controller.h index 954ffbff7..80dbcd275 100644 --- a/apps/shared/editable_cell_table_view_controller.h +++ b/apps/shared/editable_cell_table_view_controller.h @@ -4,14 +4,14 @@ #include #include #include "text_field_delegate.h" +#include "tab_table_controller.h" namespace Shared { -class EditableCellTableViewController : public ViewController, public TableViewDataSource, public SelectableTableViewDelegate, public TextFieldDelegate { +class EditableCellTableViewController : public TabTableController , public SelectableTableViewDelegate, public TextFieldDelegate { public: EditableCellTableViewController(Responder * parentResponder, KDCoordinate topMargin, KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin); - virtual View * view() override; bool textFieldDidFinishEditing(TextField * textField, const char * text) override; void tableViewDidChangeSelection(SelectableTableView * t, int previousSelectedCellX, int previousSelectedCellY) override; @@ -19,14 +19,9 @@ public: int numberOfRows() override; void willDisplayCellAtLocationWithDisplayMode(HighlightCell * cell, int i, int j, Poincare::Expression::FloatDisplayMode FloatDisplayMode); KDCoordinate rowHeight(int j) override; - KDCoordinate cumulatedHeightFromIndex(int j) override; - int indexFromCumulatedHeight(KDCoordinate offsetY) override; void didBecomeFirstResponder() override; void viewWillAppear() override; - void willExitResponderChain(Responder * nextFirstResponder) override; -protected: - SelectableTableView m_selectableTableView; private: TextFieldDelegateApp * textFieldDelegateApp() override; static constexpr KDCoordinate k_cellHeight = 20; @@ -35,7 +30,6 @@ private: virtual float dataAtLocation(int columnIndex, int rowIndex) = 0; virtual int numberOfElements() = 0; virtual int maxNumberOfElements() const = 0; - virtual Responder * tabController() const = 0; }; } diff --git a/apps/shared/ok_view.cpp b/apps/shared/ok_view.cpp index 4773a2389..bb49b69b2 100644 --- a/apps/shared/ok_view.cpp +++ b/apps/shared/ok_view.cpp @@ -34,7 +34,7 @@ void OkView::drawRect(KDContext * ctx, KDRect rect) const { ctx->blendRectWithMask(frame, KDColorBlack, (const uint8_t *)okMask, s_okWorkingBuffer); } -KDSize OkView::minimalSizeForOptimalDisplay() { +KDSize OkView::minimalSizeForOptimalDisplay() const { return KDSize(k_okSize, k_okSize); } diff --git a/apps/shared/ok_view.h b/apps/shared/ok_view.h index e3d354394..c5128f1a9 100644 --- a/apps/shared/ok_view.h +++ b/apps/shared/ok_view.h @@ -9,7 +9,7 @@ class OkView : public View { public: using View::View; void drawRect(KDContext * ctx, KDRect rect) const override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; constexpr static KDCoordinate k_okSize = 20; }; diff --git a/apps/shared/tab_table_controller.cpp b/apps/shared/tab_table_controller.cpp new file mode 100644 index 000000000..20632a3b1 --- /dev/null +++ b/apps/shared/tab_table_controller.cpp @@ -0,0 +1,49 @@ +#include "tab_table_controller.h" + +namespace Shared { + +TabTableController::TabTableController(Responder * parentResponder, KDCoordinate topMargin, + KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin, SelectableTableViewDelegate * delegate, bool showIndicators) : + ViewController(parentResponder), + m_selectableTableView(SelectableTableView(this, this, topMargin, rightMargin, bottomMargin, leftMargin, + delegate, showIndicators, true, Palette::WallScreenDark)) +{ +} + +View * TabTableController::view() { + return &m_selectableTableView; +} + +void TabTableController::didBecomeFirstResponder() { + app()->setFirstResponder(&m_selectableTableView); +} + +KDCoordinate TabTableController::cumulatedWidthFromIndex(int i) { + return i*columnWidth(0); +} + +KDCoordinate TabTableController::cumulatedHeightFromIndex(int j) { + return j*rowHeight(0); +} + +int TabTableController::indexFromCumulatedWidth(KDCoordinate offsetX) { + return (offsetX-1) / columnWidth(0); +} + +int TabTableController::indexFromCumulatedHeight(KDCoordinate offsetY) { + return (offsetY-1) / rowHeight(0); +} + +void TabTableController::viewWillAppear() { + m_selectableTableView.reloadData(); +} + +void TabTableController::willExitResponderChain(Responder * nextFirstResponder) { + if (nextFirstResponder == tabController()) { + m_selectableTableView.deselectTable(); + m_selectableTableView.scrollToCell(0,0); + } +} + +} + diff --git a/apps/shared/tab_table_controller.h b/apps/shared/tab_table_controller.h new file mode 100644 index 000000000..3aa531b49 --- /dev/null +++ b/apps/shared/tab_table_controller.h @@ -0,0 +1,29 @@ +#ifndef SHARED_TAB_TABLE_CONTROLLER_H +#define SHARED_TAB_TABLE_CONTROLLER_H + +#include + +namespace Shared { + +class TabTableController : public ViewController, public TableViewDataSource { +public: + TabTableController(Responder * parentResponder, KDCoordinate topMargin, + KDCoordinate rightMargin, KDCoordinate bottomMargin, KDCoordinate leftMargin, SelectableTableViewDelegate * delegate, bool showIndicators); + virtual View * view() override; + + KDCoordinate cumulatedHeightFromIndex(int j) override; + int indexFromCumulatedHeight(KDCoordinate offsetY) override; + KDCoordinate cumulatedWidthFromIndex(int i) override; + int indexFromCumulatedWidth(KDCoordinate offsetX) override; + void didBecomeFirstResponder() override; + void viewWillAppear() override; + void willExitResponderChain(Responder * nextFirstResponder) override; +protected: + SelectableTableView m_selectableTableView; + virtual Responder * tabController() const = 0; +}; + +} + +#endif + diff --git a/apps/statistics/box_banner_view.cpp b/apps/statistics/box_banner_view.cpp index bfb1f2bfd..fe21b8b23 100644 --- a/apps/statistics/box_banner_view.cpp +++ b/apps/statistics/box_banner_view.cpp @@ -12,9 +12,9 @@ int BoxBannerView::numberOfSubviews() const { return 2; } -TextView * BoxBannerView::textViewAtIndex(int index) { - TextView * textViews[2] = {&m_calculationName, &m_calculationValue}; - return textViews[index]; +TextView * BoxBannerView::textViewAtIndex(int index) const { + const TextView * textViews[2] = {&m_calculationName, &m_calculationValue}; + return (TextView *)textViews[index]; } } diff --git a/apps/statistics/box_banner_view.h b/apps/statistics/box_banner_view.h index 9dc2b7096..66cbaec87 100644 --- a/apps/statistics/box_banner_view.h +++ b/apps/statistics/box_banner_view.h @@ -11,7 +11,7 @@ public: BoxBannerView(); private: int numberOfSubviews() const override; - TextView * textViewAtIndex(int i) override; + TextView * textViewAtIndex(int i) const override; PointerTextView m_calculationName; BufferTextView m_calculationValue; }; diff --git a/apps/statistics/calculation_controller.cpp b/apps/statistics/calculation_controller.cpp index 38051d539..7b8fd715f 100644 --- a/apps/statistics/calculation_controller.cpp +++ b/apps/statistics/calculation_controller.cpp @@ -5,19 +5,18 @@ #include #include +using namespace Shared; using namespace Poincare; namespace Statistics { CalculationController::CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store) : - ViewController(parentResponder), + TabTableController(parentResponder, Metric::CommonTopMargin, Metric::CommonRightMargin, Metric::CommonBottomMargin, Metric::CommonLeftMargin, nullptr, true), ButtonRowDelegate(header, nullptr), m_titleCells{EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small), EvenOddPointerTextCell(KDText::FontSize::Small)}, m_calculationCells{EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small), EvenOddBufferTextCell(KDText::FontSize::Small)}, - m_selectableTableView(SelectableTableView(this, this, Metric::CommonTopMargin, Metric::CommonRightMargin, Metric::CommonBottomMargin, Metric::CommonLeftMargin, - nullptr, true, true, Palette::WallScreenDark)), m_store(store) { for (int k = 0; k < k_maxNumberOfDisplayableRows; k++) { @@ -30,10 +29,6 @@ const char * CalculationController::title() const { return "Stats"; } -View * CalculationController::view() { - return &m_selectableTableView; -} - bool CalculationController::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Up) { m_selectableTableView.deselectTable(); @@ -49,7 +44,7 @@ void CalculationController::didBecomeFirstResponder() { } else { m_selectableTableView.selectCellAtLocation(m_selectableTableView.selectedColumn(), m_selectableTableView.selectedRow()); } - app()->setFirstResponder(&m_selectableTableView); + TabTableController::didBecomeFirstResponder(); } bool CalculationController::isEmpty() const { @@ -105,22 +100,6 @@ KDCoordinate CalculationController::rowHeight(int j) { return k_cellHeight; } -KDCoordinate CalculationController::cumulatedWidthFromIndex(int i) { - return i*k_cellWidth; -} - -KDCoordinate CalculationController::cumulatedHeightFromIndex(int j) { - return j*k_cellHeight; -} - -int CalculationController::indexFromCumulatedWidth(KDCoordinate offsetX) { - return (offsetX-1) / k_cellWidth; -} - -int CalculationController::indexFromCumulatedHeight(KDCoordinate offsetY) { - return (offsetY-1) / k_cellHeight; -} - HighlightCell * CalculationController::reusableCell(int index, int type) { assert(index < k_totalNumberOfRows); if (type == 0) { @@ -137,16 +116,6 @@ int CalculationController::typeAtLocation(int i, int j) { return i; } -void CalculationController::viewWillAppear() { - m_selectableTableView.reloadData(); -} - -void CalculationController::willExitResponderChain(Responder * nextFirstResponder) { - if (nextFirstResponder == tabController()) { - m_selectableTableView.deselectTable(); - } -} - Responder * CalculationController::tabController() const { return (parentResponder()->parentResponder()->parentResponder()); } diff --git a/apps/statistics/calculation_controller.h b/apps/statistics/calculation_controller.h index ac58513c4..62f667cb7 100644 --- a/apps/statistics/calculation_controller.h +++ b/apps/statistics/calculation_controller.h @@ -3,15 +3,16 @@ #include #include "store.h" +#include "../shared/tab_table_controller.h" + namespace Statistics { -class CalculationController : public ViewController, public ButtonRowDelegate, public AlternateEmptyViewDelegate, public TableViewDataSource { +class CalculationController : public Shared::TabTableController, public ButtonRowDelegate, public AlternateEmptyViewDelegate { public: CalculationController(Responder * parentResponder, ButtonRowController * header, Store * store); const char * title() const override; - View * view() override; bool handleEvent(Ion::Events::Event event) override; void didBecomeFirstResponder() override; @@ -24,24 +25,17 @@ public: void willDisplayCellAtLocation(HighlightCell * 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; HighlightCell * reusableCell(int index, int type) override; int reusableCellCount(int type) override; int typeAtLocation(int i, int j) override; - void viewWillAppear() override; - void willExitResponderChain(Responder * nextFirstResponder) override; private: - Responder * tabController() const; + Responder * tabController() const override; constexpr static int k_totalNumberOfRows = 13; constexpr static int k_maxNumberOfDisplayableRows = 11; static constexpr KDCoordinate k_cellHeight = 20; static constexpr KDCoordinate k_cellWidth = Ion::Display::Width/2 - Metric::CommonRightMargin/2 - Metric::CommonLeftMargin/2; EvenOddPointerTextCell m_titleCells[k_maxNumberOfDisplayableRows]; EvenOddBufferTextCell m_calculationCells[k_maxNumberOfDisplayableRows]; - SelectableTableView m_selectableTableView; Store * m_store; }; diff --git a/apps/statistics/histogram_banner_view.cpp b/apps/statistics/histogram_banner_view.cpp index f7267e19b..5c4223885 100644 --- a/apps/statistics/histogram_banner_view.cpp +++ b/apps/statistics/histogram_banner_view.cpp @@ -16,9 +16,9 @@ int HistogramBannerView::numberOfSubviews() const { return 3; } -TextView * HistogramBannerView::textViewAtIndex(int i) { - TextView * textViews[3] = {&m_intervalView, &m_sizeView, &m_frequencyView}; - return textViews[i]; +TextView * HistogramBannerView::textViewAtIndex(int i) const { + const TextView * textViews[3] = {&m_intervalView, &m_sizeView, &m_frequencyView}; + return (TextView *)textViews[i]; } } diff --git a/apps/statistics/histogram_banner_view.h b/apps/statistics/histogram_banner_view.h index f3bea11a1..3a122c632 100644 --- a/apps/statistics/histogram_banner_view.h +++ b/apps/statistics/histogram_banner_view.h @@ -11,7 +11,7 @@ public: HistogramBannerView(); private: int numberOfSubviews() const override; - TextView * textViewAtIndex(int i) override; + TextView * textViewAtIndex(int i) const override; BufferTextView m_intervalView; BufferTextView m_sizeView; BufferTextView m_frequencyView; diff --git a/escher/Makefile b/escher/Makefile index 1b9732665..9bd2101d2 100644 --- a/escher/Makefile +++ b/escher/Makefile @@ -53,6 +53,7 @@ objs += $(addprefix escher/src/,\ table_cell.o\ table_view.o\ table_view_data_source.o\ + text_cursor_view.o\ text_field.o\ text_view.o\ tiled_view.o\ diff --git a/escher/include/escher/button.h b/escher/include/escher/button.h index 74df45378..025b4fdb5 100644 --- a/escher/include/escher/button.h +++ b/escher/include/escher/button.h @@ -11,7 +11,7 @@ public: Button(Responder * parentResponder, const char * textBody, Invocation invocation, KDText::FontSize size = KDText::FontSize::Small); bool handleEvent(Ion::Events::Event event) override; void setBackgroundColor(KDColor backgroundColor); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: constexpr static KDCoordinate k_verticalMargin = 5; constexpr static KDCoordinate k_horizontalMargin = 10; diff --git a/escher/include/escher/chevron_view.h b/escher/include/escher/chevron_view.h index 68310a6af..a3494e5f6 100644 --- a/escher/include/escher/chevron_view.h +++ b/escher/include/escher/chevron_view.h @@ -7,7 +7,7 @@ class ChevronView : public View { public: ChevronView(); void drawRect(KDContext * ctx, KDRect rect) const override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; /* k_chevronHeight and k_chevronWidth are the dimensions of the chevron. */ constexpr static KDCoordinate k_chevronHeight = 10; constexpr static KDCoordinate k_chevronWidth = 8; diff --git a/escher/include/escher/editable_text_cell.h b/escher/include/escher/editable_text_cell.h index fccbced28..635ce9ec5 100644 --- a/escher/include/escher/editable_text_cell.h +++ b/escher/include/escher/editable_text_cell.h @@ -20,7 +20,7 @@ public: void didBecomeFirstResponder() override; bool isEditing(); void setEditing(bool isEditing); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; constexpr static int k_bufferLength = 255; private: constexpr static KDCoordinate k_separatorThickness = 1; diff --git a/escher/include/escher/even_odd_expression_cell.h b/escher/include/escher/even_odd_expression_cell.h index eee6dd413..05daf3818 100644 --- a/escher/include/escher/even_odd_expression_cell.h +++ b/escher/include/escher/even_odd_expression_cell.h @@ -13,7 +13,7 @@ public: void setExpression(Poincare::ExpressionLayout * expressionLayout); void setBackgroundColor(KDColor backgroundColor); void setTextColor(KDColor textColor); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; void setAlignment(float horizontalAlignment, float verticalAlignment); int numberOfSubviews() const override; View * subviewAtIndex(int index) override; diff --git a/escher/include/escher/expression_view.h b/escher/include/escher/expression_view.h index bedfc08c1..660b4a441 100644 --- a/escher/include/escher/expression_view.h +++ b/escher/include/escher/expression_view.h @@ -20,7 +20,7 @@ public: void setBackgroundColor(KDColor backgroundColor); void setTextColor(KDColor textColor); void setAlignment(float horizontalAlignment, float verticalAlignment); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: /* Warning: we do not need to delete the previous expression layout when * deleting object or setting a new expression layout. Indeed, the expression diff --git a/escher/include/escher/key_view.h b/escher/include/escher/key_view.h index 8307a6e24..dff4b57bf 100644 --- a/escher/include/escher/key_view.h +++ b/escher/include/escher/key_view.h @@ -15,7 +15,7 @@ public: }; KeyView(Type type); void drawRect(KDContext * ctx, KDRect rect) const override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; constexpr static KDCoordinate k_keySize = 8; private: const uint8_t * mask() const; diff --git a/escher/include/escher/switch_view.h b/escher/include/escher/switch_view.h index a69b12b51..51a3b2081 100644 --- a/escher/include/escher/switch_view.h +++ b/escher/include/escher/switch_view.h @@ -9,7 +9,7 @@ public: bool state(); void setState(bool state); void drawRect(KDContext * ctx, KDRect rect) const override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: /* k_switchHeight and k_switchWidth are the dimensions of the switch * (including the outline of the switch). The outline thickness is diff --git a/escher/include/escher/tab_view_cell.h b/escher/include/escher/tab_view_cell.h index 67e7d2760..078f24787 100644 --- a/escher/include/escher/tab_view_cell.h +++ b/escher/include/escher/tab_view_cell.h @@ -11,7 +11,7 @@ public: void setName(const char * name); void setActive(bool active); void setSelected(bool selected); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; protected: #if ESCHER_VIEW_LOGGING const char * className() const override; diff --git a/escher/include/escher/text_cursor_view.h b/escher/include/escher/text_cursor_view.h new file mode 100644 index 000000000..2ae5605b5 --- /dev/null +++ b/escher/include/escher/text_cursor_view.h @@ -0,0 +1,14 @@ +#ifndef ESCHER_TEXT_CURSOR_VIEW_H +#define ESCHER_TEXT_CURSOR_VIEW_H + +#include + +class TextCursorView : public View { +public: + using View::View; + void drawRect(KDContext * ctx, KDRect rect) const override; + KDSize minimalSizeForOptimalDisplay() const override; +}; + +#endif + diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index cf6727d64..4eaa8177b 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -3,6 +3,7 @@ #include #include +#include #include class TextField : public ScrollableView { @@ -25,7 +26,7 @@ public: * buffer, nothing is done (not even adding few letters from the text to reach * the maximum buffer capacity. */ void insertTextAtLocation(const char * text, int location); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; void setTextFieldDelegate(TextFieldDelegate * delegate); bool handleEvent(Ion::Events::Event event) override; protected: @@ -50,11 +51,15 @@ protected: void reinitDraftTextBuffer(); void setCursorLocation(int location); void insertTextAtLocation(const char * text, int location); - KDSize minimalSizeForOptimalDisplay() override; - KDCoordinate textHeight(); + KDSize minimalSizeForOptimalDisplay() const override; + KDCoordinate textHeight() const; KDCoordinate charWidth(); void deleteCharPrecedingCursor(); + View * subviewAtIndex(int index) override; private: + int numberOfSubviews() const override; + void layoutSubviews() override; + TextCursorView m_cursorView; bool m_isEditing; char * m_textBuffer; char * m_draftTextBuffer; diff --git a/escher/include/escher/text_view.h b/escher/include/escher/text_view.h index 427d26601..918dc1481 100644 --- a/escher/include/escher/text_view.h +++ b/escher/include/escher/text_view.h @@ -15,7 +15,7 @@ public: void setBackgroundColor(KDColor backgroundColor); void setTextColor(KDColor textColor); void setAlignment(float horizontalAlignment, float verticalAlignment); - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; virtual const char * text() const = 0; virtual void setText(const char * text) = 0; protected: diff --git a/escher/include/escher/view.h b/escher/include/escher/view.h index 151809654..73f73f1e2 100644 --- a/escher/include/escher/view.h +++ b/escher/include/escher/view.h @@ -37,7 +37,7 @@ public: KDRect bounds() const; View * subview(int index); - virtual KDSize minimalSizeForOptimalDisplay(); + virtual KDSize minimalSizeForOptimalDisplay() const; #if ESCHER_VIEW_LOGGING friend std::ostream &operator<<(std::ostream &os, View &view); diff --git a/escher/include/escher/warning_controller.h b/escher/include/escher/warning_controller.h index 8ea8bb5f4..3a459dfd8 100644 --- a/escher/include/escher/warning_controller.h +++ b/escher/include/escher/warning_controller.h @@ -20,7 +20,7 @@ private: int numberOfSubviews() const override; View * subviewAtIndex(int index) override; void layoutSubviews() override; - KDSize minimalSizeForOptimalDisplay() override; + KDSize minimalSizeForOptimalDisplay() const override; private: constexpr static KDCoordinate k_verticalMargin = 40; constexpr static KDCoordinate k_horizontalMargin = 20; diff --git a/escher/src/button.cpp b/escher/src/button.cpp index 1d5a5b84d..6bfc3f053 100644 --- a/escher/src/button.cpp +++ b/escher/src/button.cpp @@ -36,7 +36,7 @@ void Button::setBackgroundColor(KDColor backgroundColor) { markRectAsDirty(bounds()); } -KDSize Button::minimalSizeForOptimalDisplay() { +KDSize Button::minimalSizeForOptimalDisplay() const { KDSize textSize = m_pointerTextView.minimalSizeForOptimalDisplay(); return KDSize(textSize.width() + k_horizontalMargin, textSize.height() + k_verticalMargin); } diff --git a/escher/src/chevron_view.cpp b/escher/src/chevron_view.cpp index d4350eebf..ddfe7d9ad 100644 --- a/escher/src/chevron_view.cpp +++ b/escher/src/chevron_view.cpp @@ -32,6 +32,6 @@ void ChevronView::drawRect(KDContext * ctx, KDRect rect) const { ctx->blendRectWithMask(frame, Palette::YellowDark, (const uint8_t *)chevronMask, s_workingBuffer); } -KDSize ChevronView::minimalSizeForOptimalDisplay() { +KDSize ChevronView::minimalSizeForOptimalDisplay() const { return KDSize(k_chevronRightMargin+k_chevronWidth, k_chevronHeight); } diff --git a/escher/src/editable_text_cell.cpp b/escher/src/editable_text_cell.cpp index f3fced261..e80fd7947 100644 --- a/escher/src/editable_text_cell.cpp +++ b/escher/src/editable_text_cell.cpp @@ -57,6 +57,6 @@ void EditableTextCell::setEditing(bool isEditing) { m_textField.setEditing(isEditing); } -KDSize EditableTextCell::minimalSizeForOptimalDisplay() { +KDSize EditableTextCell::minimalSizeForOptimalDisplay() const { return m_textField.minimalSizeForOptimalDisplay(); } diff --git a/escher/src/even_odd_expression_cell.cpp b/escher/src/even_odd_expression_cell.cpp index 63781525b..1dd696d4e 100644 --- a/escher/src/even_odd_expression_cell.cpp +++ b/escher/src/even_odd_expression_cell.cpp @@ -31,7 +31,7 @@ void EvenOddExpressionCell::setTextColor(KDColor textColor) { m_expressionView.setTextColor(textColor); } -KDSize EvenOddExpressionCell::minimalSizeForOptimalDisplay() { +KDSize EvenOddExpressionCell::minimalSizeForOptimalDisplay() const { return m_expressionView.minimalSizeForOptimalDisplay(); } diff --git a/escher/src/expression_view.cpp b/escher/src/expression_view.cpp index 58bf3ef20..26e282e5e 100644 --- a/escher/src/expression_view.cpp +++ b/escher/src/expression_view.cpp @@ -32,7 +32,7 @@ void ExpressionView::setAlignment(float horizontalAlignment, float verticalAlign markRectAsDirty(bounds()); } -KDSize ExpressionView::minimalSizeForOptimalDisplay() { +KDSize ExpressionView::minimalSizeForOptimalDisplay() const { if (m_expressionLayout == nullptr) { return KDSizeZero; } diff --git a/escher/src/key_view.cpp b/escher/src/key_view.cpp index 598fc2149..8ca55f4fd 100644 --- a/escher/src/key_view.cpp +++ b/escher/src/key_view.cpp @@ -82,7 +82,7 @@ void KeyView::drawRect(KDContext * ctx, KDRect rect) const { ctx->blendRectWithMask(frame, KDColorBlack, mask(), s_keyWorkingBuffer); } -KDSize KeyView::minimalSizeForOptimalDisplay() { +KDSize KeyView::minimalSizeForOptimalDisplay() const { return KDSize(k_keySize, k_keySize); } diff --git a/escher/src/switch_view.cpp b/escher/src/switch_view.cpp index 6a1465024..16e1ce66a 100644 --- a/escher/src/switch_view.cpp +++ b/escher/src/switch_view.cpp @@ -41,6 +41,6 @@ void SwitchView::drawRect(KDContext * ctx, KDRect rect) const { } } -KDSize SwitchView::minimalSizeForOptimalDisplay() { +KDSize SwitchView::minimalSizeForOptimalDisplay() const { return KDSize(2*k_separatorThickness + k_switchMargin + k_switchWidth, k_switchHeight); } diff --git a/escher/src/tab_view_cell.cpp b/escher/src/tab_view_cell.cpp index 01365e99f..e6a57109e 100644 --- a/escher/src/tab_view_cell.cpp +++ b/escher/src/tab_view_cell.cpp @@ -27,7 +27,7 @@ void TabViewCell::setSelected(bool selected) { markRectAsDirty(bounds()); } -KDSize TabViewCell::minimalSizeForOptimalDisplay() { +KDSize TabViewCell::minimalSizeForOptimalDisplay() const { return KDText::stringSize(m_name, KDText::FontSize::Small); } diff --git a/escher/src/text_cursor_view.cpp b/escher/src/text_cursor_view.cpp new file mode 100644 index 000000000..ba136c17d --- /dev/null +++ b/escher/src/text_cursor_view.cpp @@ -0,0 +1,11 @@ +#include + +void TextCursorView::drawRect(KDContext * ctx, KDRect rect) const { + KDCoordinate height = bounds().height(); + ctx->fillRect(KDRect(0, 0, 1, height), KDColorBlack); +} + +KDSize TextCursorView::minimalSizeForOptimalDisplay() const { + return KDSize(1, 0); +} + diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 7f98266b2..11353fe50 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -22,7 +22,7 @@ TextField::ContentView::ContentView(char * textBuffer, char * draftTextBuffer, s void TextField::ContentView::drawRect(KDContext * ctx, KDRect rect) const { ctx->fillRect(rect, m_backgroundColor); KDSize textSize = KDText::stringSize(text(), m_fontSize); - KDPoint origin(m_horizontalAlignment*(m_frame.width() - textSize.width()), + KDPoint origin(m_horizontalAlignment*(m_frame.width() - textSize.width()-m_cursorView.minimalSizeForOptimalDisplay().width()), m_verticalAlignment*(m_frame.height() - textSize.height())); ctx->drawString(text(), origin, m_fontSize, m_textColor, m_backgroundColor); } @@ -31,7 +31,8 @@ void TextField::ContentView::reload() { KDSize textSize = KDText::stringSize(text(), m_fontSize); KDPoint origin(m_horizontalAlignment*(m_frame.width() - textSize.width()), m_verticalAlignment*(m_frame.height() - textSize.height())); - KDRect dirtyZone(origin, textSize); + KDSize textAndCursorSize = KDSize(textSize.width()+ m_cursorView.minimalSizeForOptimalDisplay().width(), textSize.height()); + KDRect dirtyZone(origin, textAndCursorSize); markRectAsDirty(dirtyZone); } @@ -71,8 +72,8 @@ void TextField::ContentView::setText(const char * text) { reload(); if (m_isEditing) { strlcpy(m_draftTextBuffer, text, m_textBufferSize); - m_currentCursorLocation = strlen(text); - m_currentTextLength = m_currentCursorLocation; + m_currentTextLength = strlen(text); + setCursorLocation(m_currentTextLength); } else { strlcpy(m_textBuffer, text, m_textBufferSize); } @@ -104,6 +105,7 @@ void TextField::ContentView::setEditing(bool isEditing) { } m_isEditing = isEditing; markRectAsDirty(bounds()); + layoutSubviews(); } void TextField::ContentView::reinitDraftTextBuffer() { @@ -116,6 +118,7 @@ void TextField::ContentView::setCursorLocation(int location) { location = location < 0 ? 0 : location; location = location > (signed char)m_currentTextLength ? m_currentTextLength : location; m_currentCursorLocation = location; + layoutSubviews(); } void TextField::ContentView::insertTextAtLocation(const char * text, int location) { @@ -134,14 +137,15 @@ void TextField::ContentView::insertTextAtLocation(const char * text, int locatio reload(); } -KDSize TextField::ContentView::minimalSizeForOptimalDisplay() { +KDSize TextField::ContentView::minimalSizeForOptimalDisplay() const { if (m_isEditing) { - return KDText::stringSize(m_draftTextBuffer, m_fontSize); + KDSize textSize = KDText::stringSize(m_draftTextBuffer, m_fontSize); + return KDSize(textSize.width()+m_cursorView.minimalSizeForOptimalDisplay().width(), textSize.height()); } return KDSize(0, textHeight()); } -KDCoordinate TextField::ContentView::textHeight() { +KDCoordinate TextField::ContentView::textHeight() const { KDSize textSize = KDText::stringSize(" ", m_fontSize); return textSize.height(); } @@ -158,13 +162,32 @@ void TextField::ContentView::deleteCharPrecedingCursor() { } reload(); m_currentTextLength--; - m_currentCursorLocation--; + setCursorLocation(m_currentCursorLocation-1); for (int k = m_currentCursorLocation; k < (signed char)m_currentTextLength; k ++) { m_draftTextBuffer[k] = m_draftTextBuffer[k+1]; } m_draftTextBuffer[m_currentTextLength] = 0; } +int TextField::ContentView::numberOfSubviews() const { + return 1; +} + +View * TextField::ContentView::subviewAtIndex(int index) { + return &m_cursorView; +} + +void TextField::ContentView::layoutSubviews() { + if (!m_isEditing) { + m_cursorView.setFrame(KDRectZero); + return; + } + KDSize textSize = KDText::stringSize(text(), m_fontSize); + KDCoordinate cursorWidth = m_cursorView.minimalSizeForOptimalDisplay().width(); + KDRect frame(m_horizontalAlignment*(m_frame.width() - textSize.width()-cursorWidth)+ m_currentCursorLocation * charWidth(), m_verticalAlignment*(m_frame.height() - textSize.height()), cursorWidth, textSize.height()); + m_cursorView.setFrame(frame); +} + TextField::TextField(Responder * parentResponder, char * textBuffer, char * draftTextBuffer, size_t textBufferSize, TextFieldDelegate * delegate, KDText::FontSize size, float horizontalAlignment, float verticalAlignment, KDColor textColor, KDColor backgroundColor) : @@ -229,7 +252,7 @@ void TextField::insertTextAtLocation(const char * text, int location) { m_contentView.insertTextAtLocation(text, location); } -KDSize TextField::minimalSizeForOptimalDisplay() { +KDSize TextField::minimalSizeForOptimalDisplay() const { return KDSize(0, m_contentView.textHeight()); } @@ -287,9 +310,9 @@ bool TextField::handleEvent(Ion::Events::Event event) { return true; } if (event == Ion::Events::Back && isEditing()) { - m_delegate->textFieldDidAbortEditing(this, text()); setEditing(false); reloadScroll(); + m_delegate->textFieldDidAbortEditing(this, text()); return true; } return false; @@ -305,10 +328,10 @@ bool TextField::cursorIsBeforeScrollingFrame() { } bool TextField::cursorIsAfterScrollingFrame() { - return cursorLocation() * m_contentView.charWidth() - m_manualScrolling > bounds().width(); + KDCoordinate cursorWidth = m_contentView.subviewAtIndex(0)->minimalSizeForOptimalDisplay().width(); + return cursorLocation() * m_contentView.charWidth()+cursorWidth - m_manualScrolling > bounds().width(); } - void TextField::scrollToCursor() { if (!isEditing()) { return; @@ -318,7 +341,8 @@ void TextField::scrollToCursor() { setContentOffset(KDPoint(m_manualScrolling, 0)); } if (cursorIsAfterScrollingFrame()) { - m_manualScrolling = cursorLocation() * m_contentView.charWidth() - bounds().width(); + KDCoordinate cursorWidth = m_contentView.subviewAtIndex(0)->minimalSizeForOptimalDisplay().width(); + m_manualScrolling = cursorLocation() * m_contentView.charWidth()+cursorWidth - bounds().width(); setContentOffset(KDPoint(m_manualScrolling, 0)); } } @@ -327,7 +351,8 @@ void TextField::scrollToAvoidWhiteSpace() { if (m_manualScrolling == 0 || m_manualScrolling + bounds().width() <= textLength() * m_contentView.charWidth()) { return; } - m_manualScrolling = textLength() * m_contentView.charWidth()-bounds().width(); + KDCoordinate cursorWidth = m_contentView.subviewAtIndex(0)->minimalSizeForOptimalDisplay().width(); + m_manualScrolling = textLength() * m_contentView.charWidth()+cursorWidth-bounds().width(); setContentOffset(KDPoint(m_manualScrolling, 0)); } diff --git a/escher/src/text_view.cpp b/escher/src/text_view.cpp index bf3daace5..895413738 100644 --- a/escher/src/text_view.cpp +++ b/escher/src/text_view.cpp @@ -27,7 +27,7 @@ void TextView::setAlignment(float horizontalAlignment, float verticalAlignment) markRectAsDirty(bounds()); } -KDSize TextView::minimalSizeForOptimalDisplay() { +KDSize TextView::minimalSizeForOptimalDisplay() const { return KDText::stringSize(text(), m_fontSize); } diff --git a/escher/src/view.cpp b/escher/src/view.cpp index 0d21015ee..bfff7a4d7 100644 --- a/escher/src/view.cpp +++ b/escher/src/view.cpp @@ -163,7 +163,7 @@ KDRect View::absoluteVisibleFrame() const { } } -KDSize View::minimalSizeForOptimalDisplay() { +KDSize View::minimalSizeForOptimalDisplay() const { return KDSizeZero; } diff --git a/escher/src/warning_controller.cpp b/escher/src/warning_controller.cpp index 88cb3bea3..2ea81ea05 100644 --- a/escher/src/warning_controller.cpp +++ b/escher/src/warning_controller.cpp @@ -23,7 +23,7 @@ void WarningController::ContentView::layoutSubviews() { m_textView.setFrame(bounds()); } -KDSize WarningController::ContentView::minimalSizeForOptimalDisplay() { +KDSize WarningController::ContentView::minimalSizeForOptimalDisplay() const { KDSize textSize = m_textView.minimalSizeForOptimalDisplay(); return KDSize(textSize.width() + k_horizontalMargin, textSize.height() + k_verticalMargin); }