Numworks Epsilon  1.4.1
Graphing Calculator Operating System
values_controller.cpp
Go to the documentation of this file.
1 #include "values_controller.h"
3 #include "../constant.h"
4 #include "../apps_container.h"
5 #include <assert.h>
6 
7 using namespace Poincare;
8 
9 namespace Shared {
10 
11 ValuesController::ValuesController(Responder * parentResponder, ButtonRowController * header, I18n::Message parameterTitle, IntervalParameterController * intervalParameterController, Interval * interval) :
12  EditableCellTableViewController(parentResponder),
13  ButtonRowDelegate(header, nullptr),
14  m_interval(interval),
15  m_numberOfColumns(0),
16  m_numberOfColumnsNeedUpdate(true),
17  m_abscissaTitleCell(nullptr),
18  m_abscissaCells{},
19  m_abscissaParameterController(this, intervalParameterController, parameterTitle),
20  m_setIntervalButton(this, I18n::Message::IntervalSet, Invocation([](void * context, void * sender) {
21  ValuesController * valuesController = (ValuesController *) context;
22  StackViewController * stack = ((StackViewController *)valuesController->stackController());
23  stack->push(valuesController->intervalParameterController());
24  }, this), KDText::FontSize::Small)
25 {
26 }
27 
28 const char * ValuesController::title() {
29  return I18n::translate(I18n::Message::ValuesTab);
30 }
31 
36  }
37  return m_numberOfColumns;
38 }
39 
41  return m_interval;
42 }
43 
45  if (event == Ion::Events::Down) {
46  if (selectedRow() == -1) {
50  return true;
51  }
52  return false;
53  }
54 
55  if (event == Ion::Events::Up) {
56  if (selectedRow() == -1) {
58  app()->setFirstResponder(tabController());
59  return true;
60  }
63  return true;
64  }
65  if (event == Ion::Events::Backspace && selectedRow() > 0 &&
69  return true;
70  }
71  if (event == Ion::Events::OK || event == Ion::Events::EXE) {
72  if (selectedRow() == -1) {
73  return header()->handleEvent(event);
74  }
75  if (selectedRow() == 0) {
76  if (selectedColumn() == 0) {
77  configureAbscissa();
78  return true;
79  }
80  configureFunction();
81  return true;
82  }
83  return false;
84  }
85  if (selectedRow() == -1) {
86  return header()->handleEvent(event);
87  }
88  if (event == Ion::Events::Copy && selectedRow() > 0 && selectedColumn() > 0) {
91  return true;
92  }
93  return false;
94 }
95 
98  if (selectedRow() == -1) {
101  } else {
102  header()->setSelectedButton(-1);
103  }
104 }
105 
107  if (nextFirstResponder == tabController()) {
110  header()->setSelectedButton(-1);
111  }
112 }
113 
115  if (isEmpty()) {
116  return 0;
117  }
118  return 1;
119 }
120 
122  return (Button *)&m_setIntervalButton;
123 }
124 
126  willDisplayCellAtLocationWithDisplayMode(cell, i, j, PrintFloat::Mode::Default);
127  if (cellAtLocationIsEditable(i, j)) {
128  return;
129  }
130  // The cell is not a title cell and not editable
131  if (j > 0 && i > 0) {
132  char buffer[PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits)];
133  // Special case: last row
134  if (j == numberOfRows() - 1) {
135  int numberOfIntervalElements = m_interval->numberOfElements();
136  if (numberOfIntervalElements < Interval::k_maxNumberOfElements) {
137  buffer[0] = 0;
138  EvenOddBufferTextCell * myValueCell = (EvenOddBufferTextCell *)cell;
139  myValueCell->setText(buffer);
140  return;
141  }
142  }
143  // The cell is a value cell
144  EvenOddBufferTextCell * myValueCell = (EvenOddBufferTextCell *)cell;
145  double x = m_interval->element(j-1);
146  PrintFloat::convertFloatToText<double>(evaluationOfAbscissaAtColumn(x, i), buffer, PrintFloat::bufferSizeForFloatsWithPrecision(Constant::LargeNumberOfSignificantDigits), Constant::LargeNumberOfSignificantDigits);
147  myValueCell->setText(buffer);
148  }
149 }
150 
152  switch (i) {
153  case 0:
154  return k_abscissaCellWidth;
155  default:
156  return k_ordinateCellWidth;
157  }
158 }
159 
161  if (i == 0) {
162  return 0;
163  } else {
165  }
166 }
167 
169  if (offsetX <= k_abscissaCellWidth) {
170  return 0;
171  }
172  return (offsetX - k_abscissaCellWidth)/k_ordinateCellWidth+1;
173 }
174 
176  assert(index >= 0);
177  switch (type) {
178  case 0:
179  assert(index == 0);
180  return m_abscissaTitleCell;
181  case 1:
182  return functionTitleCells(index);
183  case 2:
184  assert(index < k_maxNumberOfAbscissaCells);
185  return m_abscissaCells[index];
186  case 3:
187  return floatCells(index);
188  default:
189  assert(false);
190  return nullptr;
191  }
192 }
193 
195  switch (type) {
196  case 0:
197  return 1;
198  case 1:
199  return maxNumberOfFunctions();
200  case 2:
201  return k_maxNumberOfAbscissaCells;
202  case 3:
203  return maxNumberOfCells();
204  default:
205  assert(false);
206  return 0;
207  }
208 }
209 
211  if (j == 0) {
212  if (i == 0) {
213  return 0;
214  }
215  return 1;
216  }
217  if (i == 0) {
218  return 2;
219  }
220  return 3;
221 }
222 
224  if (functionStore()->numberOfActiveFunctions() == 0) {
225  return true;
226  }
227  return false;
228 }
229 
231  return tabController();
232 }
233 
236  header()->setSelectedButton(-1);
237 }
238 
242 }
243 
244 Function * ValuesController::functionAtColumn(int i) {
245  assert(i > 0);
246  return functionStore()->activeFunctionAtIndex(i-1);
247 }
248 
249 Responder * ValuesController::tabController() const {
251 }
252 
255 }
256 
257 void ValuesController::configureAbscissa() {
259  stack->push(&m_abscissaParameterController);
260 }
261 
262 void ValuesController::configureFunction() {
263 #if COPY_COLUMN
264 #else
265  /* Temporary: the sequence value controller does not have a function parameter
266  * controller yet but it shoult come soon. */
267  if (functionParameterController() == nullptr) {
268  return;
269  }
270 #endif
271  functionParameterController()->setFunction(functionAtColumn(selectedColumn()));
273  stack->push(functionParameterController());
274 }
275 
276 bool ValuesController::cellAtLocationIsEditable(int columnIndex, int rowIndex) {
277  if (rowIndex > 0 && columnIndex == 0) {
278  return true;
279  }
280  return false;
281 }
282 
283 bool ValuesController::setDataAtLocation(double floatBody, int columnIndex, int rowIndex) {
284  m_interval->setElement(rowIndex-1, floatBody);
285  return true;
286 }
287 
288 double ValuesController::dataAtLocation(int columnIndex, int rowIndex) {
289  return m_interval->element(rowIndex-1);
290 }
291 
292 int ValuesController::numberOfElements() {
293  return m_interval->numberOfElements();
294 }
295 
296 int ValuesController::maxNumberOfElements() const {
298 }
299 
300 double ValuesController::evaluationOfAbscissaAtColumn(double abscissa, int columnIndex) {
301  Function * function = functionAtColumn(columnIndex);
302  TextFieldDelegateApp * myApp = (TextFieldDelegateApp *)app();
303  return function->evaluateAtAbscissa(abscissa, myApp->localContext());
304 }
305 
307  SelectableTableView * tableView = new SelectableTableView(this);
308  tableView->setVerticalCellOverlap(0);
309  tableView->setTopMargin(k_topMargin);
310  tableView->setRightMargin(k_rightMargin);
311  tableView->setBottomMargin(k_bottomMargin);
312  tableView->setLeftMargin(k_leftMargin);
314  tableView->setIndicatorThickness(13);
315 
316  m_abscissaTitleCell = new EvenOddMessageTextCell(KDText::FontSize::Small);
317  for (int i = 0; i < k_maxNumberOfAbscissaCells; i++) {
318  m_abscissaCells[i] = new EvenOddEditableTextCell(tableView, this, m_draftTextBuffer, KDText::FontSize::Small);
319  }
320  return tableView;
321 }
322 
324  delete m_abscissaTitleCell;
325  m_abscissaTitleCell = nullptr;
326  for (int i = 0; i < k_maxNumberOfAbscissaCells; i++) {
327  delete m_abscissaCells[i];
328  m_abscissaCells[i] = nullptr;
329  }
331 }
332 
334  m_numberOfColumns = 1+functionStore()->numberOfActiveFunctions();
335 }
336 
337 }
338 
bool isEmpty() const override
int typeAtLocation(int i, int j) override
void setLeftMargin(KDCoordinate m)
Definition: scroll_view.h:19
static constexpr KDCoordinate k_bottomMargin
void willDisplayCellAtLocationWithDisplayMode(HighlightCell *cell, int i, int j, Poincare::PrintFloat::Mode mode)
KDCoordinate cumulatedWidthFromIndex(int i) override
#define assert(e)
Definition: assert.h:9
void setBackgroundColor(KDColor c)
Definition: scroll_view.h:32
HighlightCell * selectedCell()
void(* Function)(const char *input)
Definition: command.h:11
void didBecomeFirstResponder() override
void setBottomMargin(KDCoordinate m)
Definition: scroll_view.h:17
constexpr Event EXE
Definition: events.h:114
StackViewController * stackController() const
int16_t KDCoordinate
Definition: coordinate.h:6
double element(int i)
Definition: interval.cpp:28
int numberOfButtons(ButtonRowController::Position) const override
void push(ViewController *vc, KDColor textColor=Palette::SubTab, KDColor backgroundColor=KDColorWhite, KDColor separatorColor=Palette::GreyBright)
Responder * parentResponder() const
Definition: responder.cpp:12
void setVerticalCellOverlap(KDCoordinate o)
Definition: table_view.h:14
void setElement(int i, double f)
Definition: interval.cpp:61
constexpr Event Up
Definition: events.h:62
constexpr Event Down
Definition: events.h:63
virtual void willDisplayCellAtLocation(HighlightCell *cell, int i, int j) override
bool selectCellAtLocation(int i, int j, bool setFirstResponder=true)
virtual void scrollToCell(int i, int j)
Definition: table_view.cpp:26
static constexpr KDCoordinate k_abscissaCellWidth
HighlightCell * reusableCell(int index, int type) override
int numberOfElements()
Definition: interval.cpp:15
Responder * defaultController() override
static constexpr int k_maxNumberOfElements
Definition: interval.h:22
bool setDataAtLocation(double floatBody, int columnIndex, int rowIndex) override
static constexpr KDCoordinate k_topMargin
void setText(const char *textContent)
void store(const char *storedText)
Definition: clipboard.cpp:9
void reloadData(bool setFirstResponder=true)
enum Message uint16_t enum Language uint16_t const char * translate(Message m, Language l=(Language) 0)
Definition: i18n.cpp:5
virtual bool handleEvent(Ion::Events::Event event) override
Button * buttonAtIndex(int index, ButtonRowController::Position position) const override
ButtonRowController * header()
void setTopMargin(KDCoordinate m)
Definition: scroll_view.h:13
int reusableCellCount(int type) override
void willExitResponderChain(Responder *nextFirstResponder) override
virtual IntervalParameterController * intervalParameterController()=0
void unloadView(View *view) override
static constexpr int LargeNumberOfSignificantDigits
Definition: constant.h:6
bool handleEvent(Ion::Events::Event event) override
void setIndicatorThickness(KDCoordinate t)
Definition: scroll_view.h:37
KDCoordinate columnWidth(int i) override
static constexpr KDCoordinate k_leftMargin
const char * title() override
virtual void updateNumberOfColumns()
bool setSelectedButton(int selectedButton)
constexpr Event Copy
Definition: events.h:123
virtual Function * activeFunctionAtIndex(int i)
void setRightMargin(KDCoordinate m)
Definition: scroll_view.h:15
void setFirstResponder(Responder *responder)
Definition: app.cpp:62
Definition: view.h:23
static constexpr KDCoordinate k_ordinateCellWidth
static Clipboard * sharedClipboard()
Definition: clipboard.cpp:5
void deleteElementAtIndex(int index)
Definition: interval.cpp:20
App * app()
Definition: responder.cpp:77
constexpr Event OK
Definition: events.h:65
Definition: button.h:10
SelectableTableView * selectableTableView()
static constexpr KDCoordinate k_rightMargin
#define true
Definition: stdbool.h:8
void unloadView(View *view) override
int indexFromCumulatedWidth(KDCoordinate offsetX) override
static constexpr KDColor WallScreenDark
Definition: palette.h:20
constexpr Event Backspace
Definition: events.h:76