diff --git a/escher/include/escher/text_input.h b/escher/include/escher/text_input.h index 78565df97..8fbffe151 100644 --- a/escher/include/escher/text_input.h +++ b/escher/include/escher/text_input.h @@ -16,6 +16,7 @@ public: bool setCursorLocation(const char * location); virtual void scrollToCursor(); void resetSelection() { contentView()->resetSelection(); } + void deleteSelectedText(); protected: class ContentView : public View { public: @@ -41,12 +42,12 @@ protected: void addSelection(const char * left, const char * right); bool resetSelection(); // returns true if the selection was indeed reset bool selectionIsEmpty() const; - virtual size_t deleteSelectedText() {return 0;} //TODO LEA + virtual size_t deleteSelectedText() { return 0;} //TODO LEA + void reloadRectFromPosition(const char * position, bool includeFollowingLines = false); const char * m_selectionStart; const char * m_selectionEnd; protected: virtual void layoutSubviews(bool force = false) override; - void reloadRectFromPosition(const char * position, bool includeFollowingLines = false); void reloadRectFromAndToPositions(const char * start, const char * end); virtual KDRect glyphFrameAtPosition(const char * buffer, const char * position) const = 0; virtual KDRect dirtyRectFromPosition(const char * position, bool includeFollowingLines) const; diff --git a/escher/src/text_area.cpp b/escher/src/text_area.cpp index 765f87f37..6c82056c9 100644 --- a/escher/src/text_area.cpp +++ b/escher/src/text_area.cpp @@ -42,11 +42,7 @@ bool TextArea::handleEventWithText(const char * text, bool indentation, bool for // Delete the selected text if needed if (!contentView()->selectionIsEmpty()) { - size_t removedLength = contentView()->deleteSelectedText(); - if (contentView()->selectionEnd() == cursorLocation()) { - setCursorLocation(cursorLocation() - removedLength); - } - contentView()->resetSelection(); + deleteSelectedText(); } /* Compute the indentation. If the text cannot be inserted with the @@ -132,13 +128,7 @@ bool TextArea::handleEvent(Ion::Events::Event event) { } return TextInput::moveCursorRight(); } - if (event == Ion::Events::Backspace) { - if (contentView()->selectionIsEmpty()) { - return removePreviousGlyph(); - } - contentView()->deleteSelectedText(); - return true; - } + if (event.hasText()) { return handleEventWithText(event.text()); } @@ -156,7 +146,18 @@ bool TextArea::handleEvent(Ion::Events::Event event) { if (event == Ion::Events::Paste) { return handleEventWithText(Clipboard::sharedClipboard()->storedText()); } - if (event == Ion::Events::Up) { + + // The following events need a scrollToCursor and return true + if (event == Ion::Events::Backspace) { + if (contentView()->selectionIsEmpty()) { + if (!removePreviousGlyph()) { + return false; + } + } else { + deleteSelectedText(); + return true; + } + } else if (event == Ion::Events::Up) { contentView()->resetSelection(); contentView()->moveCursorGeo(0, -1); } else if (event == Ion::Events::Down) { @@ -164,10 +165,9 @@ bool TextArea::handleEvent(Ion::Events::Event event) { contentView()->moveCursorGeo(0, 1); } else if (event == Ion::Events::Clear) { if (!contentView()->selectionIsEmpty()) { - contentView()->deleteSelectedText(); + deleteSelectedText(); return true; - } - if (!contentView()->removeEndOfLine()) { + } else if (!contentView()->removeEndOfLine()) { contentView()->removeStartOfLine(); } } else { @@ -517,7 +517,12 @@ bool TextArea::ContentView::removeStartOfLine() { size_t TextArea::ContentView::deleteSelectedText() { assert(!selectionIsEmpty()); - return m_text.removeText(m_selectionStart, m_selectionEnd); + size_t removedLength = m_text.removeText(m_selectionStart, m_selectionEnd); + /* We cannot call resetSelection() because m_selectionStart and m_selectionEnd + * are invalid */ + m_selectionStart = nullptr; + m_selectionEnd = nullptr; + return removedLength; } KDRect TextArea::ContentView::glyphFrameAtPosition(const char * text, const char * position) const { diff --git a/escher/src/text_input.cpp b/escher/src/text_input.cpp index 8bf2ce60e..c76b57997 100644 --- a/escher/src/text_input.cpp +++ b/escher/src/text_input.cpp @@ -84,6 +84,9 @@ void TextInput::ContentView::reloadRectFromPosition(const char * position, bool } void TextInput::ContentView::reloadRectFromAndToPositions(const char * start, const char * end) { + if (start == end) { + return; + } KDRect startFrame = glyphFrameAtPosition(text(), start); KDRect endFrame = glyphFrameAtPosition(text(), end); bool onSameLine = startFrame.y() == endFrame.y(); @@ -132,6 +135,17 @@ void TextInput::scrollToCursor() { scrollToContentRect(contentView()->cursorRect(), true); } +void TextInput::deleteSelectedText() { + assert(!contentView()->selectionIsEmpty()); + const char * previousSelectionStart = contentView()->selectionStart(); + const char * previousSelectionEnd = contentView()->selectionEnd(); + size_t removedLength = contentView()->deleteSelectedText(); + if (previousSelectionEnd == contentView()->cursorLocation()) { + setCursorLocation(contentView()->cursorLocation() - removedLength); + } + contentView()->reloadRectFromPosition(previousSelectionStart, true); +} + bool TextInput::setCursorLocation(const char * location) { assert(location != nullptr); const char * adjustedLocation = maxCharPointer(location, text());