Numworks Epsilon  1.4.1
Graphing Calculator Operating System
editor_controller.cpp
Go to the documentation of this file.
1 #include "editor_controller.h"
2 #include "menu_controller.h"
5 #include <apps/code/app.h>
6 #include <escher/metric.h>
7 #include <ion.h>
8 
9 namespace Code {
10 
12  ViewController(nullptr),
13  m_textArea(this),
14  m_areaBuffer(nullptr),
15  m_script(Ion::Storage::Record()),
16  m_menuController(menuController)
17 {
18  m_textArea.setDelegate(this);
19 }
20 
22  delete m_areaBuffer;
23  m_areaBuffer = nullptr;
24 }
25 
27  m_script = script;
28  const char * scriptBody = m_script.readContent();
29  size_t scriptBodySize = strlen(scriptBody)+1;
30  size_t availableScriptSize = scriptBodySize + Ion::Storage::sharedStorage()->availableSize();
31  assert(m_areaBuffer == nullptr);
32  m_areaBuffer = new char[availableScriptSize];
33  strlcpy(m_areaBuffer, scriptBody, scriptBodySize);
34  m_textArea.setText(m_areaBuffer, availableScriptSize);
35 }
36 
37 // TODO: this should be done in textAreaDidFinishEditing maybe??
39  if (event == Ion::Events::OK || event == Ion::Events::Back) {
40  Script::ErrorStatus err = m_script.writeContent(m_areaBuffer, strlen(m_areaBuffer)+1);
42  assert(false); // This should not happen as we set the text area according to the available space in the Kallax
43  } else {
44  stackController()->pop();
45  }
46  return true;
47  }
48  return false;
49 }
50 
52  app()->setFirstResponder(&m_textArea);
53 }
54 
56  m_textArea.setCursorLocation(strlen(m_textArea.text()));
57 }
58 
60  m_menuController->scriptContentEditionDidFinish();
61  delete[] m_areaBuffer;
62  m_areaBuffer = nullptr;
63 }
64 
66  if (static_cast<App *>(textArea->app())->textInputDidReceiveEvent(textArea, event)) {
67  return true;
68  }
69  if (event == Ion::Events::EXE) {
70  // Auto-Indent
71  char * text = const_cast<char *>(textArea->text());
72  int charBeforeCursorIndex = textArea->cursorLocation()-1;
73  int indentationSize = 0;
74  // Indent more if the previous line ends with ':'.
75  if (charBeforeCursorIndex >= 0 && text[charBeforeCursorIndex] == ':') {
76  indentationSize += k_indentationSpacesNumber;
77  }
78  // Compute the indentation of the current line.
79  int indentationIndex = charBeforeCursorIndex;
80  while (indentationIndex >= 0 && text[indentationIndex] != '\n') {
81  indentationIndex--;
82  }
83  if (indentationIndex >= 0) {
84  indentationIndex++;
85  while (text[indentationIndex] == ' ') {
86  indentationSize++;
87  indentationIndex++;
88  }
89  }
90  char * indentationBuffer = new char [indentationSize+2];
91  indentationBuffer[0] = '\n';
92  for (int i = 0; i < indentationSize; i++) {
93  indentationBuffer[i+1] = ' ';
94  }
95  indentationBuffer[indentationSize+1] = 0;
96  textArea->handleEventWithText(indentationBuffer);
97  delete[] indentationBuffer;
98  return true;
99  }
100 
101  if (event == Ion::Events::Backspace) {
102  // If the cursor is on the left of the text of a line,
103  // backspace one intentation space at a time.
104  char * text = const_cast<char *>(textArea->text());
105  int charBeforeCursorIndex = textArea->cursorLocation()-1;
106  int indentationSize = 0;
107  while (charBeforeCursorIndex >= 0 && text[charBeforeCursorIndex] == ' ') {
108  charBeforeCursorIndex--;
109  indentationSize++;
110  }
111  if (charBeforeCursorIndex >= 0 && text[charBeforeCursorIndex] == '\n'
112  && indentationSize >= k_indentationSpacesNumber)
113  {
114  for (int i = 0; i < k_indentationSpacesNumber; i++) {
115  textArea->removeChar();
116  }
117  return true;
118  }
119  } else if (event == Ion::Events::Space) {
120  // If the cursor is on the left of the text of a line,
121  // a space triggers an indentation.
122  char * text = const_cast<char *>(textArea->text());
123  int charBeforeCursorIndex = textArea->cursorLocation()-1;
124  while (charBeforeCursorIndex >= 0 && text[charBeforeCursorIndex] == ' ') {
125  charBeforeCursorIndex--;
126  }
127  if (charBeforeCursorIndex >= 0 && text[charBeforeCursorIndex] == '\n') {
128  char indentationBuffer[k_indentationSpacesNumber+1];
129  for (int i = 0; i < k_indentationSpacesNumber; i++) {
130  indentationBuffer[i] = ' ';
131  }
132  indentationBuffer[k_indentationSpacesNumber] = 0;
133  textArea->handleEventWithText(indentationBuffer);
134  return true;
135  }
136  }
137  return false;
138 }
139 
141  Code::App * codeApp = static_cast<Code::App *>(app());
142  return codeApp->pythonToolbox();
143 }
144 
145 StackViewController * EditorController::stackController() {
146  return static_cast<StackViewController *>(parentResponder());
147 }
148 
149 }
bool setCursorLocation(int location)
Definition: text_input.cpp:97
Toolbox * toolboxForTextInput(TextInput *textInput) override
Definition: app.h:13
#define assert(e)
Definition: assert.h:9
size_t cursorLocation() const
Definition: text_input.h:19
constexpr Event EXE
Definition: events.h:114
Responder * parentResponder() const
Definition: responder.cpp:12
EditorController(MenuController *menuController)
void viewDidDisappear() override
size_t strlcpy(char *dst, const char *src, size_t len)
Definition: strlcpy.c:3
const char * readContent() const
Definition: script.cpp:22
constexpr Event Back
Definition: events.h:66
bool handleEvent(Ion::Events::Event event) override
void setScript(Script script)
static Storage * sharedStorage()
Definition: storage.cpp:22
Definition: app.cpp:7
size_t strlen(const char *s)
Definition: strlen.c:3
void setDelegate(TextAreaDelegate *delegate)
Definition: text_area.h:13
PythonToolbox * pythonToolbox()
Definition: app.h:39
bool textAreaDidReceiveEvent(TextArea *textArea, Ion::Events::Event event) override
constexpr Event Space
Definition: events.h:177
bool removeChar()
Definition: text_input.cpp:80
const char * text() const
Definition: text_input.h:14
void viewWillAppear() override
void setText(char *textBuffer, size_t textBufferSize)
Definition: text_area.cpp:340
void setFirstResponder(Responder *responder)
Definition: app.cpp:62
size_t availableSize()
Definition: storage.cpp:56
App * app()
Definition: responder.cpp:77
constexpr Event OK
Definition: events.h:65
Definition: backlight.h:6
void didBecomeFirstResponder() override
ErrorStatus writeContent(const char *data, size_t size)
Definition: script.cpp:28
bool handleEventWithText(const char *text, bool indentation=false) override
Definition: text_area.cpp:294
constexpr Event Backspace
Definition: events.h:76