Numworks Epsilon  1.4.1
Graphing Calculator Operating System
edit_expression_controller.cpp
Go to the documentation of this file.
2 #include "../apps_container.h"
3 #include "app.h"
4 #include <assert.h>
5 
6 using namespace Shared;
7 
8 namespace Calculation {
9 
10 EditExpressionController::ContentView::ContentView(Responder * parentResponder, TableView * subview, TextFieldDelegate * textFieldDelegate) :
11  View(),
12  m_mainView(subview),
13  m_textField(parentResponder, m_textBody, TextField::maxBufferSize(), textFieldDelegate)
14 {
15  m_textBody[0] = 0;
16 }
17 
18 int EditExpressionController::ContentView::numberOfSubviews() const {
19  return 2;
20 }
21 
22 View * EditExpressionController::ContentView::subviewAtIndex(int index) {
23  View * views[2] = {m_mainView, &m_textField};
24  return views[index];
25 }
26 
27 void EditExpressionController::ContentView::layoutSubviews() {
28  KDRect mainViewFrame(0, 0, bounds().width(), bounds().height() - k_textFieldHeight-k_separatorThickness);
29  m_mainView->setFrame(mainViewFrame);
30  KDRect inputViewFrame(k_textMargin, bounds().height() - k_textFieldHeight, bounds().width()-k_textMargin, k_textFieldHeight);
31  m_textField.setFrame(inputViewFrame);
32 }
33 
34 void EditExpressionController::ContentView::drawRect(KDContext * ctx, KDRect rect) const {
35  // Draw the separator
36  ctx->fillRect(KDRect(0, bounds().height() -k_textFieldHeight-k_separatorThickness, bounds().width(), k_separatorThickness), Palette::GreyMiddle);
37  // Color the margin
38  ctx->fillRect(KDRect(0, bounds().height() -k_textFieldHeight, k_textMargin, k_textFieldHeight), m_textField.backgroundColor());
39 }
40 
41 TextField * EditExpressionController::ContentView::textField() {
42  return &m_textField;
43 }
44 
45 TableView * EditExpressionController::ContentView::mainView() {
46  return m_mainView;
47 }
48 
49 EditExpressionController::EditExpressionController(Responder * parentResponder, HistoryController * historyController, CalculationStore * calculationStore) :
50  DynamicViewController(parentResponder),
51  m_historyController(historyController),
52  m_calculationStore(calculationStore)
53 {
54  m_cacheBuffer[0] = 0;
55 }
56 
58  return ((ContentView *)view())->textField()->text();
59 }
60 
62  TextField * tf = ((ContentView *)view())->textField();
63  tf->setEditing(true, false);
64  tf->handleEventWithText(text);
65 }
66 
68  if (event == Ion::Events::Up) {
69  if (m_calculationStore->numberOfCalculations() > 0) {
70  m_cacheBuffer[0] = 0;
71  ((ContentView *)view())->textField()->setEditing(false, false);
72  app()->setFirstResponder(m_historyController);
73  }
74  return true;
75  }
76  return false;
77 }
78 
80  int lastRow = m_calculationStore->numberOfCalculations() > 0 ? m_calculationStore->numberOfCalculations()-1 : 0;
81  m_historyController->scrollToCell(0, lastRow);
82  ((ContentView *)view())->textField()->setEditing(true, false);
83  app()->setFirstResponder(((ContentView *)view())->textField());
84 }
85 
87  if (textField->isEditing() && textField->textFieldShouldFinishEditing(event) && textField->draftTextLength() == 0 && m_cacheBuffer[0] != 0) {
88  App * calculationApp = (App *)app();
89  /* The input text store in m_cacheBuffer might have beed correct the first
90  * time but then be too long when replacing ans in another context */
91  if (!calculationApp->textInputIsCorrect(m_cacheBuffer)) {
92  return true;
93  }
94  m_calculationStore->push(m_cacheBuffer, calculationApp->localContext());
95  m_historyController->reload();
96  ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1);
97  return true;
98  }
99  return textFieldDelegateApp()->textFieldDidReceiveEvent(textField, event);
100 }
101 
103  App * calculationApp = (App *)app();
104  strlcpy(m_cacheBuffer, textBody(), TextField::maxBufferSize());
105  m_calculationStore->push(textBody(), calculationApp->localContext());
106  m_historyController->reload();
107  ((ContentView *)view())->mainView()->scrollToCell(0, m_historyController->numberOfRows()-1);
108  ((ContentView *)view())->textField()->setEditing(true);
109  ((ContentView *)view())->textField()->setText("");
110  return true;
111 }
112 
113 bool EditExpressionController::textFieldDidAbortEditing(::TextField * textField, const char * text) {
114  ((ContentView *)view())->textField()->setEditing(true);
115  ((ContentView *)view())->textField()->setText(text);
116  return false;
117 }
118 
119 TextFieldDelegateApp * EditExpressionController::textFieldDelegateApp() {
120  return (App *)app();
121 }
122 
123 View * EditExpressionController::loadView() {
124  return new ContentView(this, (TableView *)m_historyController->view(), this);
125 }
126 
127 void EditExpressionController::unloadView(View * view) {
128  delete view;
129 }
130 
133  m_historyController->viewDidDisappear();
134 }
135 
136 }
bool isEditing() const
Definition: text_field.cpp:175
Calculation * push(const char *text, Poincare::Context *context)
bool textFieldDidFinishEditing(::TextField *textField, const char *text, Ion::Events::Event event) override
static constexpr int maxBufferSize()
Definition: text_field.h:23
void setText(const char *text)
Definition: text_field.cpp:184
constexpr Event Up
Definition: events.h:62
size_t strlcpy(char *dst, const char *src, size_t len)
Definition: strlcpy.c:3
bool textFieldShouldFinishEditing(Ion::Events::Event event)
Definition: text_field.h:27
virtual void setEditing(bool isEditing, bool reinitDraftBuffer=true)
Definition: text_field.cpp:196
virtual Poincare::Context * localContext()
bool handleEvent(Ion::Events::Event event) override
static constexpr KDColor GreyMiddle
Definition: palette.h:14
virtual bool textFieldDidReceiveEvent(TextField *textField, Ion::Events::Event event) override
Definition: rect.h:26
void fillRect(KDRect rect, KDColor color)
Definition: context_rect.cpp:8
bool handleEventWithText(const char *text, bool indenting=false) override
Definition: text_field.cpp:303
size_t draftTextLength() const
Definition: text_field.cpp:179
void setFirstResponder(Responder *responder)
Definition: app.cpp:62
Definition: view.h:23
bool textFieldDidAbortEditing(::TextField *textField, const char *text) override
bool textFieldDidReceiveEvent(::TextField *textField, Ion::Events::Event event) override
bool textInputIsCorrect(const char *text)
Definition: app.cpp:68
EditExpressionController(Responder *parentResponder, HistoryController *historyController, CalculationStore *calculationStore)
App * app()
Definition: responder.cpp:77