| @@ -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() | ~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 | juce_UseDebuggingNewOperator | ||||
| @@ -656,7 +694,6 @@ private: | |||||
| const tchar passwordCharacter; | const tchar passwordCharacter; | ||||
| TextAtom tempAtom; | TextAtom tempAtom; | ||||
| TextEditorIterator (const TextEditorIterator&); | |||||
| const TextEditorIterator& operator= (const TextEditorIterator&); | const TextEditorIterator& operator= (const TextEditorIterator&); | ||||
| void moveToEndOfLastAtom() throw() | void moveToEndOfLastAtom() throw() | ||||
| @@ -831,13 +868,15 @@ public: | |||||
| class TextEditorViewport : public Viewport | class TextEditorViewport : public Viewport | ||||
| { | { | ||||
| TextEditor* const owner; | TextEditor* const owner; | ||||
| float lastWordWrapWidth; | |||||
| TextEditorViewport (const TextEditorViewport&); | TextEditorViewport (const TextEditorViewport&); | ||||
| const TextEditorViewport& operator= (const TextEditorViewport&); | const TextEditorViewport& operator= (const TextEditorViewport&); | ||||
| public: | public: | ||||
| TextEditorViewport (TextEditor* const owner_) | TextEditorViewport (TextEditor* const owner_) | ||||
| : owner (owner_) | |||||
| : owner (owner_), | |||||
| lastWordWrapWidth (0) | |||||
| { | { | ||||
| } | } | ||||
| @@ -847,7 +886,13 @@ public: | |||||
| void visibleAreaChanged (int, int, int, int) | 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) | if (textStartIndex > textEndIndex && textEndIndex > 0) | ||||
| swapVariables (textStartIndex, textEndIndex); | 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) | if (isSelecting) | ||||
| { | { | ||||
| moveCaret (newPosition); | moveCaret (newPosition); | ||||
| repaintText (selectionStart, selectionEnd); | |||||
| const int oldSelStart = selectionStart; | |||||
| const int oldSelEnd = selectionEnd; | |||||
| if (dragType == notDragging) | 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 | else | ||||
| { | { | ||||
| @@ -1470,6 +1529,11 @@ void TextEditor::drawContent (Graphics& g) | |||||
| const Rectangle clip (g.getClipBounds()); | const Rectangle clip (g.getClipBounds()); | ||||
| Colour selectedTextColour; | Colour selectedTextColour; | ||||
| TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); | |||||
| while (i.lineY + 200.0 < clip.getY() && i.next()) | |||||
| {} | |||||
| if (selectionStart < selectionEnd) | if (selectionStart < selectionEnd) | ||||
| { | { | ||||
| g.setColour (findColour (highlightColourId) | g.setColour (findColour (highlightColourId) | ||||
| @@ -1477,29 +1541,26 @@ void TextEditor::drawContent (Graphics& g) | |||||
| selectedTextColour = findColour (highlightedTextColourId); | 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; | const UniformTextSection* lastSection = 0; | ||||
| while (i.next() && i.lineY < clip.getBottom()) | while (i.next() && i.lineY < clip.getBottom()) | ||||
| { | { | ||||
| if (i.lineY + getHeight() >= clip.getY()) | |||||
| i.updateLineHeight(); | |||||
| i.updateLineHeight(); | |||||
| if (i.lineY + i.lineHeight >= clip.getY()) | 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) | 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 | else | ||||
| { | { | ||||
| @@ -2327,7 +2375,7 @@ int TextEditor::indexAtPosition (const float x, const float y) throw() | |||||
| if (wordWrapWidth > 0) | if (wordWrapWidth > 0) | ||||
| { | { | ||||
| TextEditorIterator i (sections, getWordWrapWidth(), passwordCharacter); | |||||
| TextEditorIterator i (sections, wordWrapWidth, passwordCharacter); | |||||
| while (i.next()) | while (i.next()) | ||||
| { | { | ||||