Merge changes Ib4a80a3c,Ifa81feaa,I0af0da6b

* changes:
  [escher] Add a cursor to text fields
  [apps] Correct bug: return boolean forgotten
  [apps/shared] Factorize tab table controller in a class
This commit is contained in:
Émilie Feral
2017-03-16 15:10:40 +01:00
committed by Gerrit
61 changed files with 237 additions and 194 deletions

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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:

View File

@@ -19,7 +19,7 @@ void ScrollableExpressionView::setBackgroundColor(KDColor backgroundColor) {
m_expressionView.setBackgroundColor(backgroundColor);
}
KDSize ScrollableExpressionView::minimalSizeForOptimalDisplay() {
KDSize ScrollableExpressionView::minimalSizeForOptimalDisplay() const {
return m_expressionView.minimalSizeForOptimalDisplay();
}

View File

@@ -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;

View File

@@ -31,8 +31,4 @@ bool TextField::handleEvent(Ion::Events::Event event) {
return(::TextField::handleEvent(event));
}
void TextField::setEditing(bool isEditing) {
::TextField::setEditing(true);
}
}

View File

@@ -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;
};
}

View File

@@ -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];
}
}

View File

@@ -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;

View File

@@ -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];
}
}

View File

@@ -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;

View File

@@ -7,19 +7,18 @@
#include <assert.h>
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());
}

View File

@@ -4,16 +4,16 @@
#include <escher.h>
#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;
};

View File

@@ -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];
}
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -60,6 +60,7 @@ bool SubController::handleEvent(Ion::Events::Event event) {
myContainer->refreshPreferences();
StackViewController * stack = stackController();
stack->pop();
return true;
}
return false;
}

View File

@@ -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\

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -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();
}

View File

@@ -4,14 +4,14 @@
#include <escher.h>
#include <poincare.h>
#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;
};
}

View File

@@ -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);
}

View File

@@ -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;
};

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,29 @@
#ifndef SHARED_TAB_TABLE_CONTROLLER_H
#define SHARED_TAB_TABLE_CONTROLLER_H
#include <escher.h>
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

View File

@@ -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];
}
}

View File

@@ -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;
};

View File

@@ -5,19 +5,18 @@
#include <poincare.h>
#include <assert.h>
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());
}

View File

@@ -3,15 +3,16 @@
#include <escher.h>
#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;
};

View File

@@ -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];
}
}

View File

@@ -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;

View File

@@ -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\

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -0,0 +1,14 @@
#ifndef ESCHER_TEXT_CURSOR_VIEW_H
#define ESCHER_TEXT_CURSOR_VIEW_H
#include <escher/view.h>
class TextCursorView : public View {
public:
using View::View;
void drawRect(KDContext * ctx, KDRect rect) const override;
KDSize minimalSizeForOptimalDisplay() const override;
};
#endif

View File

@@ -3,6 +3,7 @@
#include <escher/scrollable_view.h>
#include <escher/text_field_delegate.h>
#include <escher/text_cursor_view.h>
#include <string.h>
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;

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -57,6 +57,6 @@ void EditableTextCell::setEditing(bool isEditing) {
m_textField.setEditing(isEditing);
}
KDSize EditableTextCell::minimalSizeForOptimalDisplay() {
KDSize EditableTextCell::minimalSizeForOptimalDisplay() const {
return m_textField.minimalSizeForOptimalDisplay();
}

View File

@@ -31,7 +31,7 @@ void EvenOddExpressionCell::setTextColor(KDColor textColor) {
m_expressionView.setTextColor(textColor);
}
KDSize EvenOddExpressionCell::minimalSizeForOptimalDisplay() {
KDSize EvenOddExpressionCell::minimalSizeForOptimalDisplay() const {
return m_expressionView.minimalSizeForOptimalDisplay();
}

View File

@@ -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;
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -0,0 +1,11 @@
#include <escher/text_cursor_view.h>
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);
}

View File

@@ -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));
}

View File

@@ -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);
}

View File

@@ -163,7 +163,7 @@ KDRect View::absoluteVisibleFrame() const {
}
}
KDSize View::minimalSizeForOptimalDisplay() {
KDSize View::minimalSizeForOptimalDisplay() const {
return KDSizeZero;
}

View File

@@ -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);
}