From 2575e3226ab59292db6f417f99f805d3b82a87a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 7 Nov 2016 14:59:01 +0100 Subject: [PATCH 1/3] [escher] add methods to add text to buffer in textfield Change-Id: I51388c7495ed8919d1f2ba48d645aee9476c5ed6 --- .../edit_expression_controller.cpp | 6 +-- apps/expression_text_field_delegate.cpp | 6 +-- escher/include/escher/text_field.h | 14 ++++-- escher/src/input_view_controller.cpp | 4 +- escher/src/text_field.cpp | 48 ++++++++++++++----- 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/apps/calculation/edit_expression_controller.cpp b/apps/calculation/edit_expression_controller.cpp index 1f6a6de0c..19e12dc57 100644 --- a/apps/calculation/edit_expression_controller.cpp +++ b/apps/calculation/edit_expression_controller.cpp @@ -61,11 +61,11 @@ const char * EditExpressionController::title() const { } const char * EditExpressionController::textBody() { - return m_contentView.textField()->textBuffer(); + return m_contentView.textField()->text(); } void EditExpressionController::setTextBody(const char * text) { - m_contentView.textField()->setTextBuffer(text); + m_contentView.textField()->setText(text); } bool EditExpressionController::handleEvent(Ion::Events::Event event) { @@ -78,7 +78,7 @@ bool EditExpressionController::handleEvent(Ion::Events::Event event) { m_calculationStore->push(&calculation); m_historyController->reload(); m_contentView.mainView()->scrollToCell(0, m_historyController->numberOfRows()-1); - m_contentView.textField()->setTextBuffer(""); + m_contentView.textField()->setText(""); return true; } case Ion::Events::Event::ESC: diff --git a/apps/expression_text_field_delegate.cpp b/apps/expression_text_field_delegate.cpp index d1494b966..e0f09a4b9 100644 --- a/apps/expression_text_field_delegate.cpp +++ b/apps/expression_text_field_delegate.cpp @@ -2,15 +2,15 @@ #include bool ExpressionTextFieldDelegate::textFieldDidReceiveEvent(TextField * textField, Ion::Events::Event event) { - if (event == Ion::Events::Event::ENTER && Expression::parse(textField->textBuffer()) == nullptr) { - if (textField->bufferLength() == 0) { + if (event == Ion::Events::Event::ENTER && Expression::parse(textField->text()) == nullptr) { + if (textField->textLength() == 0) { return true; } textField->app()->displayWarning("Attention a la syntaxe jeune padawan"); return true; } if (event == Ion::Events::Event::ENTER && - isnan(Expression::parse(textField->textBuffer())->approximate(*evaluateContext()))) { + isnan(Expression::parse(textField->text())->approximate(*evaluateContext()))) { textField->app()->displayWarning("Relis ton cours de maths, veux tu?"); return true; } diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index 735ff12a7..d1f3e52fa 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -13,11 +13,17 @@ public: void drawRect(KDContext * ctx, KDRect rect) const override; // Responder bool handleEvent(Ion::Events::Event event) override; - const char * textBuffer() const; - int bufferLength() const; - void setTextBuffer(const char * text); - KDSize minimalSizeForOptimalDisplay() override; + const char * text() const; + int textLength() const; + void setText(const char * text); + /* If the text to be appended is too long to be added without overflowing the + * buffer, nothing is done (not even adding few letters from the text to reach + * the maximum buffer capacity. */ + void appendText(const char * text); + void moveCursor(int delta); + KDSize minimalSizeForOptimalDisplay() override; protected: + void reload(); #if ESCHER_VIEW_LOGGING const char * className() const override; #endif diff --git a/escher/src/input_view_controller.cpp b/escher/src/input_view_controller.cpp index f312ba17f..426cddfe3 100644 --- a/escher/src/input_view_controller.cpp +++ b/escher/src/input_view_controller.cpp @@ -34,7 +34,7 @@ const char * InputViewController::title() const { } const char * InputViewController::textBody() { - return m_textFieldController.textField()->textBuffer(); + return m_textFieldController.textField()->text(); } void InputViewController::showInput() { @@ -42,7 +42,7 @@ void InputViewController::showInput() { } void InputViewController::setTextBody(const char * text) { - m_textFieldController.textField()->setTextBuffer(text); + m_textFieldController.textField()->setText(text); } bool InputViewController::handleEvent(Ion::Events::Event event) { diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 81918980d..499ced8b2 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -1,4 +1,5 @@ #include +#include TextField::TextField(Responder * parentResponder, char * textBuffer, size_t textBufferSize, TextFieldDelegate * delegate) : View(), @@ -24,6 +25,12 @@ const char * TextField::className() const { } #endif +void TextField::reload() { + KDSize sizeText = KDText::stringSize(m_textBuffer); + KDRect dirtyZone(0, 0, sizeText.width(), sizeText.height()); + markRectAsDirty(dirtyZone); +} + /* Responder */ bool TextField::handleEvent(Ion::Events::Event event) { @@ -45,15 +52,13 @@ bool TextField::handleEvent(Ion::Events::Event event) { return true; case Ion::Events::Event::DELETE: if (m_currentCursorPosition > 0) { - KDSize sizePreviousText = KDText::stringSize(m_textBuffer); + reload(); m_currentTextLength--; m_currentCursorPosition--; for (int k = m_currentCursorPosition; k < m_currentTextLength; k ++) { m_textBuffer[k] = m_textBuffer[k+1]; } m_textBuffer[m_currentTextLength] = 0; - KDRect dirtyZone(0, 0, sizePreviousText.width(), sizePreviousText.height()); - markRectAsDirty(dirtyZone); } return true; default: @@ -66,28 +71,47 @@ bool TextField::handleEvent(Ion::Events::Event event) { } m_textBuffer[++m_currentTextLength] = 0; m_textBuffer[m_currentCursorPosition++] = (int)event; - KDSize sizeText = KDText::stringSize(m_textBuffer); - KDRect dirtyZone(0, 0, sizeText.width(), sizeText.height()); - markRectAsDirty(dirtyZone); + reload(); } return true; } } -const char * TextField::textBuffer () const { - const char * textBuffer = (const char *)m_textBuffer; - return textBuffer; +const char * TextField::text() const { + return (const char *)m_textBuffer; } -int TextField::bufferLength () const { +int TextField::textLength() const { + assert(strlen(text()) == m_currentTextLength); return m_currentTextLength; } -void TextField::setTextBuffer(const char * text) { +void TextField::setText(const char * text) { strlcpy(m_textBuffer, text, m_textBufferSize); m_currentCursorPosition = strlen(text); m_currentTextLength = m_currentCursorPosition; - markRectAsDirty(bounds()); + reload(); +} + +void TextField::appendText(const char * text) { + int textSize = strlen(text); + if (m_currentTextLength + textSize > m_textBufferSize) { + return; + } + for (int k = m_currentTextLength; k > m_currentCursorPosition - 1; k--) { + m_textBuffer[k+textSize] = m_textBuffer[k]; + } + strlcpy(&m_textBuffer[m_currentCursorPosition], text, textSize); + m_currentCursorPosition += textSize; + m_textBuffer[m_currentCursorPosition-1] = text[textSize-1]; + m_currentTextLength += textSize; + reload(); +} + +void TextField::moveCursor(int position) { + assert(m_currentCursorPosition + position <= m_currentTextLength); + assert(m_currentCursorPosition + position >= 0); + m_currentCursorPosition += position; } KDSize TextField::minimalSizeForOptimalDisplay() { From d09a34cde7202613c9e2fb5404301430d943d3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 7 Nov 2016 15:12:15 +0100 Subject: [PATCH 2/3] [apps] Handle enter in tool box controller Change-Id: Id36bf56871b7d4245062244eaa9a2ef9f6b5a14c --- apps/tool_box_controller.cpp | 22 ++++++++++++++++++++++ apps/tool_box_controller.h | 1 + 2 files changed, 23 insertions(+) diff --git a/apps/tool_box_controller.cpp b/apps/tool_box_controller.cpp index 79ca60f41..a828b8cde 100644 --- a/apps/tool_box_controller.cpp +++ b/apps/tool_box_controller.cpp @@ -15,6 +15,12 @@ static const char * labels[] = { "Trigonometrie hyperbolique" }; +static const char * mathCommands[] = { + "abs()", + "root(,)", + "log()" +}; + ToolBoxController::ToolBoxController() : StackViewController(nullptr, this, true), m_selectableTableView(SelectableTableView(this, this)) @@ -26,6 +32,22 @@ const char * ToolBoxController::title() const { } bool ToolBoxController::handleEvent(Ion::Events::Event event) { + switch (event) { + case Ion::Events::Event::ENTER: + return handleEnter(); + default: + return false; + } +} + +bool ToolBoxController::handleEnter() { + if (m_selectableTableView.selectedRow() < 3) { + m_textFieldCaller->appendText(mathCommands[m_selectableTableView.selectedRow()]); + int cursorPosition = m_selectableTableView.selectedRow() == 1 ? -2 : -1; + m_textFieldCaller->moveCursor(cursorPosition); + app()->dismissModalViewController(); + return true; + } return false; } diff --git a/apps/tool_box_controller.h b/apps/tool_box_controller.h index 4e534b692..0f72f5ad7 100644 --- a/apps/tool_box_controller.h +++ b/apps/tool_box_controller.h @@ -19,6 +19,7 @@ public: int typeAtLocation(int i, int j) override; void setTextFieldCaller(TextField * textField); private: + bool handleEnter(); constexpr static int k_numberOfCommandRows = 3; constexpr static int k_numberOfMenuRows = 8; constexpr static int k_maxNumberOfDisplayedRows = 6; From f3bbe536bc9366babe9008b1e3d4ca7f95e2aeb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Mon, 7 Nov 2016 16:23:54 +0100 Subject: [PATCH 3/3] [apps] Add a tool box as instance variable of the app container Change-Id: I02e841da8668ca50cd7cd59101445be84244a6eb --- apps/apps_container.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/apps_container.h b/apps/apps_container.h index a88e540d6..22ffdb15a 100644 --- a/apps/apps_container.h +++ b/apps/apps_container.h @@ -5,6 +5,7 @@ #include "graph/app.h" #include "probability/app.h" #include "calculation/app.h" +#include "tool_box_controller.h" #define USE_PIC_VIEW_APP 0 #if USE_PIC_VIEW_APP @@ -29,6 +30,7 @@ private: PicViewApp m_picViewApp; #endif Context m_context; + ToolBoxController m_toolBoxController; }; #endif