diff --git a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp index 6ca27abf0d..0235ecf7fe 100644 --- a/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp +++ b/src/juce_appframework/gui/components/controls/juce_TextEditor.cpp @@ -371,6 +371,24 @@ public: } } + TextEditorIterator (const TextEditorIterator& other) throw() + : indexInText (other.indexInText), + lineY (other.lineY), + lineHeight (other.lineHeight), + maxDescent (other.maxDescent), + atomX (other.atomX), + atomRight (other.atomRight), + atom (other.atom), + currentSection (other.currentSection), + sections (other.sections), + sectionIndex (other.sectionIndex), + atomIndex (other.atomIndex), + wordWrapWidth (other.wordWrapWidth), + passwordCharacter (other.passwordCharacter), + tempAtom (other.tempAtom) + { + } + ~TextEditorIterator() throw() { } @@ -640,6 +658,26 @@ public: } } + bool getCharPosition (const int index, float& cx, float& cy, float& lineHeight_) throw() + { + while (next()) + { + cy = lineY; + + if (indexInText + atom->numChars > index) + { + updateLineHeight(); + cx = indexToX (index); + lineHeight_ = lineHeight; + return true; + } + } + + cx = atomX; + cy = lineY; + return false; + } + //============================================================================== juce_UseDebuggingNewOperator @@ -656,7 +694,6 @@ private: const tchar passwordCharacter; TextAtom tempAtom; - TextEditorIterator (const TextEditorIterator&); const TextEditorIterator& operator= (const TextEditorIterator&); void moveToEndOfLastAtom() throw() @@ -831,13 +868,15 @@ public: class TextEditorViewport : public Viewport { TextEditor* const owner; + float lastWordWrapWidth; TextEditorViewport (const TextEditorViewport&); const TextEditorViewport& operator= (const TextEditorViewport&); public: TextEditorViewport (TextEditor* const owner_) - : owner (owner_) + : owner (owner_), + lastWordWrapWidth (0) { } @@ -847,7 +886,13 @@ public: void visibleAreaChanged (int, int, int, int) { - owner->updateTextHolderSize(); + const float wordWrapWidth = owner->getWordWrapWidth(); + + if (wordWrapWidth != lastWordWrapWidth) + { + lastWordWrapWidth = wordWrapWidth; + owner->updateTextHolderSize(); + } } }; @@ -1178,23 +1223,31 @@ void TextEditor::repaintText (int textStartIndex, int textEndIndex) if (textStartIndex > textEndIndex && textEndIndex > 0) swapVariables (textStartIndex, textEndIndex); - float x, y, lh; - getCharPosition (textStartIndex, x, y, lh); - const int y1 = (int) y; + float x = 0, y = 0, lh = currentFont.getHeight(); - int y2; + const float wordWrapWidth = getWordWrapWidth(); - if (textEndIndex >= 0) - { - getCharPosition (textEndIndex, x, y, lh); - y2 = (int) (y + lh * 2.0f); - } - else + if (wordWrapWidth > 0) { - y2 = textHolder->getHeight(); - } + TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); + + i.getCharPosition (textStartIndex, x, y, lh); + + const int y1 = (int) y; + int y2; - textHolder->repaint (0, y1, textHolder->getWidth(), y2 - y1); + if (textEndIndex >= 0) + { + i.getCharPosition (textEndIndex, x, y, lh); + y2 = (int) (y + lh * 2.0f); + } + else + { + y2 = textHolder->getHeight(); + } + + textHolder->repaint (0, y1, textHolder->getWidth(), y2 - y1); + } } //============================================================================== @@ -1342,7 +1395,9 @@ void TextEditor::moveCursorTo (const int newPosition, if (isSelecting) { moveCaret (newPosition); - repaintText (selectionStart, selectionEnd); + + const int oldSelStart = selectionStart; + const int oldSelEnd = selectionEnd; if (dragType == notDragging) { @@ -1373,7 +1428,11 @@ void TextEditor::moveCursorTo (const int newPosition, } } - repaintText (selectionStart, selectionEnd); + jassert (selectionStart <= selectionEnd); + jassert (oldSelStart <= oldSelEnd); + + repaintText (jmin (oldSelStart, selectionStart), + jmax (oldSelEnd, selectionEnd)); } else { @@ -1470,6 +1529,11 @@ void TextEditor::drawContent (Graphics& g) const Rectangle clip (g.getClipBounds()); Colour selectedTextColour; + TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); + + while (i.lineY + 200.0 < clip.getY() && i.next()) + {} + if (selectionStart < selectionEnd) { g.setColour (findColour (highlightColourId) @@ -1477,29 +1541,26 @@ void TextEditor::drawContent (Graphics& g) selectedTextColour = findColour (highlightedTextColourId); - TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); + TextEditorIterator i2 (i); - while (i.next() && i.lineY < clip.getBottom()) + while (i2.next() && i2.lineY < clip.getBottom()) { - if (i.lineY + getHeight() >= clip.getY()) - i.updateLineHeight(); + i2.updateLineHeight(); - if (i.lineY + i.lineHeight >= clip.getY() - && selectionEnd >= i.indexInText - && selectionStart <= i.indexInText + i.atom->numChars) + if (i2.lineY + i2.lineHeight >= clip.getY() + && selectionEnd >= i2.indexInText + && selectionStart <= i2.indexInText + i2.atom->numChars) { - i.drawSelection (g, selectionStart, selectionEnd); + i2.drawSelection (g, selectionStart, selectionEnd); } } } - TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); const UniformTextSection* lastSection = 0; while (i.next() && i.lineY < clip.getBottom()) { - if (i.lineY + getHeight() >= clip.getY()) - i.updateLineHeight(); + i.updateLineHeight(); if (i.lineY + i.lineHeight >= clip.getY()) { @@ -2295,23 +2356,10 @@ void TextEditor::getCharPosition (const int index, float& cx, float& cy, float& if (wordWrapWidth > 0) { - TextEditorIterator i (sections, getWordWrapWidth(), passwordCharacter); - - while (i.next()) - { - cy = i.lineY; - - if (i.indexInText + i.atom->numChars > index) - { - i.updateLineHeight(); - cx = i.indexToX (index); - lineHeight = i.lineHeight; - return; - } - } + TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); - cx = i.atomX; - cy = i.lineY; + if (i.getCharPosition (index, cx, cy, lineHeight)) + return; } else { @@ -2327,7 +2375,7 @@ int TextEditor::indexAtPosition (const float x, const float y) throw() if (wordWrapWidth > 0) { - TextEditorIterator i (sections, getWordWrapWidth(), passwordCharacter); + TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); while (i.next()) {