From aea98de6ec4cd17b66e7f4d4d75aa550f73d358b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 6 Nov 2018 15:20:20 +0100 Subject: [PATCH] [apps/escher] Fix "Clear" event handling in TextFieldWithExtension --- apps/shared/text_field_with_extension.cpp | 26 +++++++++++++++++++++++ apps/shared/text_field_with_extension.h | 3 +++ escher/include/escher/text_field.h | 3 +++ escher/include/escher/text_input.h | 3 ++- escher/src/text_field.cpp | 19 ++++++++++++++++- escher/src/text_input.cpp | 6 +++++- 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/apps/shared/text_field_with_extension.cpp b/apps/shared/text_field_with_extension.cpp index 93a40b764..61797bf68 100644 --- a/apps/shared/text_field_with_extension.cpp +++ b/apps/shared/text_field_with_extension.cpp @@ -11,4 +11,30 @@ void TextFieldWithExtension::willSetCursorLocation(int * location) { } } +bool TextFieldWithExtension::privateRemoveEndOfLine() { + return removeTextBeforeExtension(false); +} + +void TextFieldWithExtension::removeWholeText() { + removeTextBeforeExtension(true); + scrollToCursor(); +} + +bool TextFieldWithExtension::removeTextBeforeExtension(bool whole) { + int extensionIndex = strlen(text()) - m_extensionLength; + assert(extensionIndex >= 0 && extensionIndex < ContentView::k_maxBufferSize - m_extensionLength); + size_t destinationIndex = whole ? 0 : cursorLocation(); + if (destinationIndex == extensionIndex) { + return false; + } + assert(destinationIndex >= 0); + assert(destinationIndex < extensionIndex); + m_contentView.willModifyTextBuffer(); + strlcpy(&(m_contentView.textBuffer()[destinationIndex]), &(m_contentView.textBuffer()[extensionIndex]), ContentView::k_maxBufferSize); + m_contentView.setCursorLocation(destinationIndex); + m_contentView.didModifyTextBuffer(); + layoutSubviews(); + return true; +} + } diff --git a/apps/shared/text_field_with_extension.h b/apps/shared/text_field_with_extension.h index 317509669..12e087ef5 100644 --- a/apps/shared/text_field_with_extension.h +++ b/apps/shared/text_field_with_extension.h @@ -25,6 +25,9 @@ public: {} private: void willSetCursorLocation(int * location) override; + bool privateRemoveEndOfLine() override; + void removeWholeText() override; + bool removeTextBeforeExtension(bool whole); size_t m_extensionLength; }; diff --git a/escher/include/escher/text_field.h b/escher/include/escher/text_field.h index 36c3df481..f04e5772a 100644 --- a/escher/include/escher/text_field.h +++ b/escher/include/escher/text_field.h @@ -56,6 +56,8 @@ protected: KDSize minimalSizeForOptimalDisplay() const override; bool removeChar() override; bool removeEndOfLine() override; + void willModifyTextBuffer(); + void didModifyTextBuffer(); /* In some app (ie Calculation), text fields record expression results whose * lengths can reach 70 (ie * [[1.234567e-123*e^(1.234567e-123*i), 1.234567e-123*e^(1.234567e-123*i)]]). @@ -80,6 +82,7 @@ protected: private: bool privateHandleEvent(Ion::Events::Event event); bool privateHandleMoveEvent(Ion::Events::Event event); + virtual void removeWholeText(); bool m_hasTwoBuffers; TextFieldDelegate * m_delegate; }; diff --git a/escher/include/escher/text_input.h b/escher/include/escher/text_input.h index b1c826ab6..826b92d21 100644 --- a/escher/include/escher/text_input.h +++ b/escher/include/escher/text_input.h @@ -46,13 +46,14 @@ protected: * buffer, nothing is done (not even adding few letters from the text to reach * the maximum buffer capacity) and false is returned. */ bool insertTextAtLocation(const char * textBuffer, int location); - virtual bool removeEndOfLine(); + bool removeEndOfLine(); ContentView * contentView() { return const_cast(nonEditableContentView()); } virtual const ContentView * nonEditableContentView() const = 0; private: virtual void willSetCursorLocation(int * location) {} + virtual bool privateRemoveEndOfLine(); }; #endif diff --git a/escher/src/text_field.cpp b/escher/src/text_field.cpp index 1f917cd01..2ab60bf26 100644 --- a/escher/src/text_field.cpp +++ b/escher/src/text_field.cpp @@ -162,6 +162,19 @@ bool TextField::ContentView::removeEndOfLine() { return true; } +void TextField::ContentView::willModifyTextBuffer() { + /* This method should be called when the buffer is modified outside the + * content view, for instance from the textfield directly. */ + reloadRectFromCursorPosition(0); +} + +void TextField::ContentView::didModifyTextBuffer() { + /* This method should be called when the buffer is modified outside the + * content view, for instance from the textfield directly. */ + m_currentDraftTextLength = strlen(m_draftTextBuffer); + layoutSubviews(); +} + void TextField::ContentView::layoutSubviews() { if (!m_isEditing) { m_cursorView.setFrame(KDRectZero); @@ -287,7 +300,7 @@ bool TextField::privateHandleEvent(Ion::Events::Event event) { } if (event == Ion::Events::Clear && isEditing()) { if (!removeEndOfLine()) { - setEditing(true, true); + removeWholeText(); } return true; } @@ -448,3 +461,7 @@ bool TextField::handleEventWithText(const char * eventText, bool indentation, bo setCursorLocation(nextCursorLocation); return m_delegate->textFieldDidHandleEvent(this, true, strlen(text()) != previousTextLength); } + +void TextField::removeWholeText() { + setEditing(true, true); +} diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index 837dec996..51c7d6dfd 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -96,9 +96,13 @@ bool TextInput::insertTextAtLocation(const char * text, int location) { } bool TextInput::removeEndOfLine() { - if (contentView()->removeEndOfLine()) { + if (privateRemoveEndOfLine()) { scrollToCursor(); return true; } return false; } + +bool TextInput::privateRemoveEndOfLine() { + return contentView()->removeEndOfLine(); +}