|
|
@@ -67,7 +67,7 @@ public: |
|
|
|
}
|
|
|
|
|
|
|
|
UniformTextSection (const UniformTextSection& other)
|
|
|
|
: font (other.font), colour (other.colour)
|
|
|
|
: font (other.font), colour (other.colour)
|
|
|
|
{
|
|
|
|
atoms.ensureStorageAllocated (other.atoms.size());
|
|
|
|
|
|
|
@@ -80,39 +80,28 @@ public: |
|
|
|
void clear()
|
|
|
|
{
|
|
|
|
for (int i = atoms.size(); --i >= 0;)
|
|
|
|
delete getAtom(i);
|
|
|
|
delete atoms.getUnchecked (i);
|
|
|
|
|
|
|
|
atoms.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
int getNumAtoms() const
|
|
|
|
{
|
|
|
|
return atoms.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
TextAtom* getAtom (const int index) const noexcept
|
|
|
|
{
|
|
|
|
return atoms.getUnchecked (index);
|
|
|
|
}
|
|
|
|
|
|
|
|
void append (const UniformTextSection& other, const juce_wchar passwordCharacter)
|
|
|
|
void append (const UniformTextSection& other, const juce_wchar passwordChar)
|
|
|
|
{
|
|
|
|
if (other.atoms.size() > 0)
|
|
|
|
{
|
|
|
|
TextAtom* const lastAtom = atoms.getLast();
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (lastAtom != nullptr)
|
|
|
|
if (TextAtom* const lastAtom = atoms.getLast())
|
|
|
|
{
|
|
|
|
if (! CharacterFunctions::isWhitespace (lastAtom->atomText.getLastCharacter()))
|
|
|
|
{
|
|
|
|
TextAtom* const first = other.getAtom(0);
|
|
|
|
TextAtom* const first = other.atoms.getUnchecked(0);
|
|
|
|
|
|
|
|
if (! CharacterFunctions::isWhitespace (first->atomText[0]))
|
|
|
|
{
|
|
|
|
lastAtom->atomText += first->atomText;
|
|
|
|
lastAtom->numChars = (uint16) (lastAtom->numChars + first->numChars);
|
|
|
|
lastAtom->width = font.getStringWidthFloat (lastAtom->getText (passwordCharacter));
|
|
|
|
lastAtom->width = font.getStringWidthFloat (lastAtom->getText (passwordChar));
|
|
|
|
delete first;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
@@ -123,30 +112,27 @@ public: |
|
|
|
|
|
|
|
while (i < other.atoms.size())
|
|
|
|
{
|
|
|
|
atoms.add (other.getAtom(i));
|
|
|
|
atoms.add (other.atoms.getUnchecked(i));
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
UniformTextSection* split (const int indexToBreakAt,
|
|
|
|
const juce_wchar passwordCharacter)
|
|
|
|
UniformTextSection* split (const int indexToBreakAt, const juce_wchar passwordChar)
|
|
|
|
{
|
|
|
|
UniformTextSection* const section2 = new UniformTextSection (String::empty,
|
|
|
|
font, colour,
|
|
|
|
passwordCharacter);
|
|
|
|
UniformTextSection* const section2 = new UniformTextSection (String::empty, font, colour, passwordChar);
|
|
|
|
int index = 0;
|
|
|
|
|
|
|
|
for (int i = 0; i < atoms.size(); ++i)
|
|
|
|
{
|
|
|
|
TextAtom* const atom = getAtom(i);
|
|
|
|
TextAtom* const atom = atoms.getUnchecked(i);
|
|
|
|
|
|
|
|
const int nextIndex = index + atom->numChars;
|
|
|
|
|
|
|
|
if (index == indexToBreakAt)
|
|
|
|
{
|
|
|
|
for (int j = i; j < atoms.size(); ++j)
|
|
|
|
section2->atoms.add (getAtom (j));
|
|
|
|
section2->atoms.add (atoms.getUnchecked (j));
|
|
|
|
|
|
|
|
for (int j = atoms.size(); --j >= i;)
|
|
|
|
atoms.remove (j);
|
|
|
@@ -158,17 +144,17 @@ public: |
|
|
|
TextAtom* const secondAtom = new TextAtom();
|
|
|
|
|
|
|
|
secondAtom->atomText = atom->atomText.substring (indexToBreakAt - index);
|
|
|
|
secondAtom->width = font.getStringWidthFloat (secondAtom->getText (passwordCharacter));
|
|
|
|
secondAtom->width = font.getStringWidthFloat (secondAtom->getText (passwordChar));
|
|
|
|
secondAtom->numChars = (uint16) secondAtom->atomText.length();
|
|
|
|
|
|
|
|
section2->atoms.add (secondAtom);
|
|
|
|
|
|
|
|
atom->atomText = atom->atomText.substring (0, indexToBreakAt - index);
|
|
|
|
atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter));
|
|
|
|
atom->width = font.getStringWidthFloat (atom->getText (passwordChar));
|
|
|
|
atom->numChars = (uint16) (indexToBreakAt - index);
|
|
|
|
|
|
|
|
for (int j = i + 1; j < atoms.size(); ++j)
|
|
|
|
section2->atoms.add (getAtom (j));
|
|
|
|
section2->atoms.add (atoms.getUnchecked (j));
|
|
|
|
|
|
|
|
for (int j = atoms.size(); --j > i;)
|
|
|
|
atoms.remove (j);
|
|
|
@@ -185,7 +171,7 @@ public: |
|
|
|
void appendAllText (MemoryOutputStream& mo) const
|
|
|
|
{
|
|
|
|
for (int i = 0; i < atoms.size(); ++i)
|
|
|
|
mo << getAtom(i)->atomText;
|
|
|
|
mo << atoms.getUnchecked(i)->atomText;
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendSubstring (MemoryOutputStream& mo, const Range<int>& range) const
|
|
|
@@ -193,7 +179,7 @@ public: |
|
|
|
int index = 0;
|
|
|
|
for (int i = 0; i < atoms.size(); ++i)
|
|
|
|
{
|
|
|
|
const TextAtom* const atom = getAtom (i);
|
|
|
|
const TextAtom* const atom = atoms.getUnchecked (i);
|
|
|
|
const int nextIndex = index + atom->numChars;
|
|
|
|
|
|
|
|
if (range.getStart() < nextIndex)
|
|
|
@@ -211,18 +197,17 @@ public: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int getTotalLength() const
|
|
|
|
int getTotalLength() const noexcept
|
|
|
|
{
|
|
|
|
int total = 0;
|
|
|
|
|
|
|
|
for (int i = atoms.size(); --i >= 0;)
|
|
|
|
total += getAtom(i)->numChars;
|
|
|
|
total += atoms.getUnchecked(i)->numChars;
|
|
|
|
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
|
|
|
void setFont (const Font& newFont,
|
|
|
|
const juce_wchar passwordCharacter)
|
|
|
|
void setFont (const Font& newFont, const juce_wchar passwordChar)
|
|
|
|
{
|
|
|
|
if (font != newFont)
|
|
|
|
{
|
|
|
@@ -231,7 +216,7 @@ public: |
|
|
|
for (int i = atoms.size(); --i >= 0;)
|
|
|
|
{
|
|
|
|
TextAtom* const atom = atoms.getUnchecked(i);
|
|
|
|
atom->width = newFont.getStringWidthFloat (atom->getText (passwordCharacter));
|
|
|
|
atom->width = newFont.getStringWidthFloat (atom->getText (passwordChar));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -239,13 +224,10 @@ public: |
|
|
|
//==============================================================================
|
|
|
|
Font font;
|
|
|
|
Colour colour;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Array <TextAtom*> atoms;
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void initialiseAtoms (const String& textToParse,
|
|
|
|
const juce_wchar passwordCharacter)
|
|
|
|
private:
|
|
|
|
void initialiseAtoms (const String& textToParse, const juce_wchar passwordChar)
|
|
|
|
{
|
|
|
|
String::CharPointerType text (textToParse.getCharPointer());
|
|
|
|
|
|
|
@@ -294,8 +276,7 @@ private: |
|
|
|
|
|
|
|
TextAtom* const atom = new TextAtom();
|
|
|
|
atom->atomText = String (start, numChars);
|
|
|
|
|
|
|
|
atom->width = font.getStringWidthFloat (atom->getText (passwordCharacter));
|
|
|
|
atom->width = font.getStringWidthFloat (atom->getText (passwordChar));
|
|
|
|
atom->numChars = (uint16) numChars;
|
|
|
|
|
|
|
|
atoms.add (atom);
|
|
|
@@ -399,9 +380,9 @@ public: |
|
|
|
moveToEndOfLastAtom();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (atomIndex >= currentSection->getNumAtoms() - 1)
|
|
|
|
else if (atomIndex >= currentSection->atoms.size() - 1)
|
|
|
|
{
|
|
|
|
if (atomIndex >= currentSection->getNumAtoms())
|
|
|
|
if (atomIndex >= currentSection->atoms.size())
|
|
|
|
{
|
|
|
|
if (++sectionIndex >= sections.size())
|
|
|
|
{
|
|
|
@@ -414,7 +395,7 @@ public: |
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const TextAtom* const lastAtom = currentSection->getAtom (atomIndex);
|
|
|
|
const TextAtom* const lastAtom = currentSection->atoms.getUnchecked (atomIndex);
|
|
|
|
|
|
|
|
if (! lastAtom->isWhitespace())
|
|
|
|
{
|
|
|
@@ -428,10 +409,10 @@ public: |
|
|
|
{
|
|
|
|
const UniformTextSection* const s = sections.getUnchecked (section);
|
|
|
|
|
|
|
|
if (s->getNumAtoms() == 0)
|
|
|
|
if (s->atoms.size() == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
const TextAtom* const nextAtom = s->getAtom (0);
|
|
|
|
const TextAtom* const nextAtom = s->atoms.getUnchecked (0);
|
|
|
|
|
|
|
|
if (nextAtom->isWhitespace())
|
|
|
|
break;
|
|
|
@@ -450,7 +431,7 @@ public: |
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (s->getNumAtoms() > 1)
|
|
|
|
if (s->atoms.size() > 1)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -466,7 +447,7 @@ public: |
|
|
|
beginNewLine();
|
|
|
|
}
|
|
|
|
|
|
|
|
atom = currentSection->getAtom (atomIndex);
|
|
|
|
atom = currentSection->atoms.getUnchecked (atomIndex);
|
|
|
|
atomRight = atomX + atom->width;
|
|
|
|
++atomIndex;
|
|
|
|
|
|
|
@@ -523,7 +504,7 @@ public: |
|
|
|
|
|
|
|
bool checkSize = false;
|
|
|
|
|
|
|
|
if (tempAtomIndex >= section->getNumAtoms())
|
|
|
|
if (tempAtomIndex >= section->atoms.size())
|
|
|
|
{
|
|
|
|
if (++tempSectionIndex >= sections.size())
|
|
|
|
break;
|
|
|
@@ -533,7 +514,7 @@ public: |
|
|
|
checkSize = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TextAtom* const nextAtom = section->getAtom (tempAtomIndex);
|
|
|
|
const TextAtom* const nextAtom = section->atoms.getUnchecked (tempAtomIndex);
|
|
|
|
|
|
|
|
if (nextAtom == nullptr)
|
|
|
|
break;
|
|
|
@@ -570,16 +551,15 @@ public: |
|
|
|
GlyphArrangement ga;
|
|
|
|
ga.addLineOfText (currentSection->font,
|
|
|
|
atom->getTrimmedText (passwordCharacter),
|
|
|
|
atomX,
|
|
|
|
(float) roundToInt (lineY + lineHeight - maxDescent));
|
|
|
|
atomX, (float) roundToInt (lineY + lineHeight - maxDescent));
|
|
|
|
ga.draw (g);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void drawSelection (Graphics& g, const Range<int>& selection) const
|
|
|
|
void drawSelection (Graphics& g, const Range<int>& selected) const
|
|
|
|
{
|
|
|
|
const int startX = roundToInt (indexToX (selection.getStart()));
|
|
|
|
const int endX = roundToInt (indexToX (selection.getEnd()));
|
|
|
|
const int startX = roundToInt (indexToX (selected.getStart()));
|
|
|
|
const int endX = roundToInt (indexToX (selected.getEnd()));
|
|
|
|
|
|
|
|
const int y = roundToInt (lineY);
|
|
|
|
const int nextY = roundToInt (lineY + lineHeight);
|
|
|
@@ -599,7 +579,7 @@ public: |
|
|
|
}
|
|
|
|
|
|
|
|
void drawSelectedText (Graphics& g,
|
|
|
|
const Range<int>& selection,
|
|
|
|
const Range<int>& selected,
|
|
|
|
const Colour& selectedTextColour) const
|
|
|
|
{
|
|
|
|
if (passwordCharacter != 0 || ! atom->isWhitespace())
|
|
|
@@ -607,24 +587,23 @@ public: |
|
|
|
GlyphArrangement ga;
|
|
|
|
ga.addLineOfText (currentSection->font,
|
|
|
|
atom->getTrimmedText (passwordCharacter),
|
|
|
|
atomX,
|
|
|
|
(float) roundToInt (lineY + lineHeight - maxDescent));
|
|
|
|
atomX, (float) roundToInt (lineY + lineHeight - maxDescent));
|
|
|
|
|
|
|
|
if (selection.getEnd() < indexInText + atom->numChars)
|
|
|
|
if (selected.getEnd() < indexInText + atom->numChars)
|
|
|
|
{
|
|
|
|
GlyphArrangement ga2 (ga);
|
|
|
|
ga2.removeRangeOfGlyphs (0, selection.getEnd() - indexInText);
|
|
|
|
ga.removeRangeOfGlyphs (selection.getEnd() - indexInText, -1);
|
|
|
|
ga2.removeRangeOfGlyphs (0, selected.getEnd() - indexInText);
|
|
|
|
ga.removeRangeOfGlyphs (selected.getEnd() - indexInText, -1);
|
|
|
|
|
|
|
|
g.setColour (currentSection->colour);
|
|
|
|
ga2.draw (g);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (selection.getStart() > indexInText)
|
|
|
|
if (selected.getStart() > indexInText)
|
|
|
|
{
|
|
|
|
GlyphArrangement ga2 (ga);
|
|
|
|
ga2.removeRangeOfGlyphs (selection.getStart() - indexInText, -1);
|
|
|
|
ga.removeRangeOfGlyphs (0, selection.getStart() - indexInText);
|
|
|
|
ga2.removeRangeOfGlyphs (selected.getStart() - indexInText, -1);
|
|
|
|
ga.removeRangeOfGlyphs (0, selected.getStart() - indexInText);
|
|
|
|
|
|
|
|
g.setColour (currentSection->colour);
|
|
|
|
ga2.draw (g);
|
|
|
@@ -726,7 +705,7 @@ private: |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool shouldWrap (const float x) const
|
|
|
|
bool shouldWrap (const float x) const noexcept
|
|
|
|
{
|
|
|
|
return (x - 0.0001f) >= wordWrapWidth;
|
|
|
|
}
|
|
|
@@ -824,12 +803,11 @@ public: |
|
|
|
|
|
|
|
int getSizeInUnits()
|
|
|
|
{
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
int n = 16;
|
|
|
|
for (int i = removedSections.size(); --i >= 0;)
|
|
|
|
n += removedSections.getUnchecked (i)->getTotalLength();
|
|
|
|
|
|
|
|
return n + 16;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
@@ -957,7 +935,6 @@ TextEditor::TextEditor (const String& name, |
|
|
|
menuActive (false),
|
|
|
|
valueTextNeedsUpdating (false),
|
|
|
|
consumeEscAndReturnKeys (true),
|
|
|
|
maxTextLength (0),
|
|
|
|
leftIndent (4),
|
|
|
|
topIndent (4),
|
|
|
|
lastTransactionTime (0),
|
|
|
@@ -982,11 +959,8 @@ TextEditor::TextEditor (const String& name, |
|
|
|
TextEditor::~TextEditor()
|
|
|
|
{
|
|
|
|
if (wasFocused)
|
|
|
|
{
|
|
|
|
ComponentPeer* const peer = getPeer();
|
|
|
|
if (peer != nullptr)
|
|
|
|
if (ComponentPeer* const peer = getPeer())
|
|
|
|
peer->dismissPendingTextInput();
|
|
|
|
}
|
|
|
|
|
|
|
|
textValue.referTo (Value());
|
|
|
|
clearInternal (0);
|
|
|
@@ -1105,7 +1079,6 @@ void TextEditor::setFont (const Font& newFont) |
|
|
|
void TextEditor::applyFontToAllText (const Font& newFont)
|
|
|
|
{
|
|
|
|
currentFont = newFont;
|
|
|
|
|
|
|
|
const Colour overallColour (findColour (textColourId));
|
|
|
|
|
|
|
|
for (int i = sections.size(); --i >= 0;)
|
|
|
@@ -1155,11 +1128,32 @@ void TextEditor::updateCaretPosition() |
|
|
|
caret->setCaretPosition (getCaretRectangle().translated (leftIndent, topIndent));
|
|
|
|
}
|
|
|
|
|
|
|
|
TextEditor::LengthAndCharacterRestriction::LengthAndCharacterRestriction (int maxLen, const String& chars)
|
|
|
|
: allowedCharacters (chars), maxLength (maxLen)
|
|
|
|
{}
|
|
|
|
|
|
|
|
String TextEditor::LengthAndCharacterRestriction::filterNewText (TextEditor& ed, const String& newInput)
|
|
|
|
{
|
|
|
|
String t (newInput);
|
|
|
|
|
|
|
|
if (allowedCharacters.isNotEmpty())
|
|
|
|
t = t.retainCharacters (allowedCharacters);
|
|
|
|
|
|
|
|
if (maxLength > 0)
|
|
|
|
t = t.substring (0, maxLength - (ed.getTotalNumChars() - ed.getHighlightedRegion().getLength()));
|
|
|
|
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::setInputFilter (InputFilter* newFilter, bool takeOwnership)
|
|
|
|
{
|
|
|
|
inputFilter.set (newFilter, takeOwnership);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::setInputRestrictions (const int maxLen,
|
|
|
|
const String& chars)
|
|
|
|
{
|
|
|
|
maxTextLength = jmax (0, maxLen);
|
|
|
|
allowedCharacters = chars;
|
|
|
|
setInputFilter (new LengthAndCharacterRestriction (maxLen, chars), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::setTextToShowWhenEmpty (const String& text, const Colour& colourToUse)
|
|
|
@@ -1262,25 +1256,11 @@ void TextEditor::textChanged() |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::returnPressed()
|
|
|
|
{
|
|
|
|
postCommandMessage (TextEditorDefs::returnKeyMessageId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::escapePressed()
|
|
|
|
{
|
|
|
|
postCommandMessage (TextEditorDefs::escapeKeyMessageId);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::addListener (TextEditorListener* const newListener)
|
|
|
|
{
|
|
|
|
listeners.add (newListener);
|
|
|
|
}
|
|
|
|
void TextEditor::returnPressed() { postCommandMessage (TextEditorDefs::returnKeyMessageId); }
|
|
|
|
void TextEditor::escapePressed() { postCommandMessage (TextEditorDefs::escapeKeyMessageId); }
|
|
|
|
|
|
|
|
void TextEditor::removeListener (TextEditorListener* const listenerToRemove)
|
|
|
|
{
|
|
|
|
listeners.remove (listenerToRemove);
|
|
|
|
}
|
|
|
|
void TextEditor::addListener (TextEditorListener* const l) { listeners.add (l); }
|
|
|
|
void TextEditor::removeListener (TextEditorListener* const l) { listeners.remove (l); }
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
void TextEditor::timerCallbackInt()
|
|
|
@@ -1430,21 +1410,13 @@ void TextEditor::updateTextHolderSize() |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int TextEditor::getTextWidth() const
|
|
|
|
{
|
|
|
|
return textHolder->getWidth();
|
|
|
|
}
|
|
|
|
|
|
|
|
int TextEditor::getTextHeight() const
|
|
|
|
{
|
|
|
|
return textHolder->getHeight();
|
|
|
|
}
|
|
|
|
int TextEditor::getTextWidth() const { return textHolder->getWidth(); }
|
|
|
|
int TextEditor::getTextHeight() const { return textHolder->getHeight(); }
|
|
|
|
|
|
|
|
void TextEditor::setIndents (const int newLeftIndent,
|
|
|
|
const int newTopIndent)
|
|
|
|
void TextEditor::setIndents (const int newLeftIndent, const int newTopIndent)
|
|
|
|
{
|
|
|
|
leftIndent = newLeftIndent;
|
|
|
|
topIndent = newTopIndent;
|
|
|
|
topIndent = newTopIndent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::setBorder (const BorderSize<int>& border)
|
|
|
@@ -1561,32 +1533,21 @@ int TextEditor::getTextIndexAt (const int x, const int y) |
|
|
|
|
|
|
|
void TextEditor::insertTextAtCaret (const String& t)
|
|
|
|
{
|
|
|
|
String newText (t);
|
|
|
|
|
|
|
|
if (allowedCharacters.isNotEmpty())
|
|
|
|
newText = newText.retainCharacters (allowedCharacters);
|
|
|
|
String newText (inputFilter != nullptr ? inputFilter->filterNewText (*this, t) : t);
|
|
|
|
|
|
|
|
if (! isMultiLine())
|
|
|
|
newText = newText.replaceCharacters ("\r\n", " ");
|
|
|
|
else
|
|
|
|
if (isMultiLine())
|
|
|
|
newText = newText.replace ("\r\n", "\n");
|
|
|
|
else
|
|
|
|
newText = newText.replaceCharacters ("\r\n", " ");
|
|
|
|
|
|
|
|
const int newCaretPos = selection.getStart() + newText.length();
|
|
|
|
const int insertIndex = selection.getStart();
|
|
|
|
const int newCaretPos = insertIndex + newText.length();
|
|
|
|
|
|
|
|
remove (selection, getUndoManager(),
|
|
|
|
newText.isNotEmpty() ? newCaretPos - 1 : newCaretPos);
|
|
|
|
|
|
|
|
if (maxTextLength > 0)
|
|
|
|
newText = newText.substring (0, maxTextLength - getTotalNumChars());
|
|
|
|
|
|
|
|
if (newText.isNotEmpty())
|
|
|
|
insert (newText,
|
|
|
|
insertIndex,
|
|
|
|
currentFont,
|
|
|
|
findColour (textColourId),
|
|
|
|
getUndoManager(),
|
|
|
|
newCaretPos);
|
|
|
|
insert (newText, insertIndex, currentFont, findColour (textColourId),
|
|
|
|
getUndoManager(), newCaretPos);
|
|
|
|
|
|
|
|
textChanged();
|
|
|
|
}
|
|
|
@@ -1714,16 +1675,12 @@ void TextEditor::paintOverChildren (Graphics& g) |
|
|
|
g.setFont (getFont());
|
|
|
|
|
|
|
|
if (isMultiLine())
|
|
|
|
{
|
|
|
|
g.drawText (textToShowWhenEmpty, getLocalBounds(),
|
|
|
|
Justification::centred, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g.drawText (textToShowWhenEmpty,
|
|
|
|
leftIndent, 0, viewport->getWidth() - leftIndent, getHeight(),
|
|
|
|
Justification::centredLeft, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getLookAndFeel().drawTextEditorOutline (g, getWidth(), getHeight(), *this);
|
|
|
@@ -1888,7 +1845,7 @@ void TextEditor::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& w |
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
bool TextEditor::moveCaretWithTransation (const int newPos, const bool selecting)
|
|
|
|
bool TextEditor::moveCaretWithTransaction (const int newPos, const bool selecting)
|
|
|
|
{
|
|
|
|
newTransaction();
|
|
|
|
moveCaretTo (newPos, selecting);
|
|
|
@@ -1904,7 +1861,7 @@ bool TextEditor::moveCaretLeft (bool moveInWholeWordSteps, bool selecting) |
|
|
|
else
|
|
|
|
--pos;
|
|
|
|
|
|
|
|
return moveCaretWithTransation (pos, selecting);
|
|
|
|
return moveCaretWithTransaction (pos, selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretRight (bool moveInWholeWordSteps, bool selecting)
|
|
|
@@ -1916,7 +1873,7 @@ bool TextEditor::moveCaretRight (bool moveInWholeWordSteps, bool selecting) |
|
|
|
else
|
|
|
|
++pos;
|
|
|
|
|
|
|
|
return moveCaretWithTransation (pos, selecting);
|
|
|
|
return moveCaretWithTransaction (pos, selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretUp (bool selecting)
|
|
|
@@ -1925,7 +1882,7 @@ bool TextEditor::moveCaretUp (bool selecting) |
|
|
|
return moveCaretToStartOfLine (selecting);
|
|
|
|
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getY() - 1.0f), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - 1.0f), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretDown (bool selecting)
|
|
|
@@ -1934,7 +1891,7 @@ bool TextEditor::moveCaretDown (bool selecting) |
|
|
|
return moveCaretToEndOfLine (selecting);
|
|
|
|
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getBottom() + 1.0f), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + 1.0f), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::pageUp (bool selecting)
|
|
|
@@ -1943,7 +1900,7 @@ bool TextEditor::pageUp (bool selecting) |
|
|
|
return moveCaretToStartOfLine (selecting);
|
|
|
|
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::pageDown (bool selecting)
|
|
|
@@ -1952,14 +1909,12 @@ bool TextEditor::pageDown (bool selecting) |
|
|
|
return moveCaretToEndOfLine (selecting);
|
|
|
|
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::scrollByLines (int deltaLines)
|
|
|
|
{
|
|
|
|
ScrollBar* scrollbar = viewport->getVerticalScrollBar();
|
|
|
|
|
|
|
|
if (scrollbar != nullptr)
|
|
|
|
if (ScrollBar* scrollbar = viewport->getVerticalScrollBar())
|
|
|
|
scrollbar->moveScrollbarInSteps (deltaLines);
|
|
|
|
}
|
|
|
|
|
|
|
@@ -1977,24 +1932,24 @@ bool TextEditor::scrollUp() |
|
|
|
|
|
|
|
bool TextEditor::moveCaretToTop (bool selecting)
|
|
|
|
{
|
|
|
|
return moveCaretWithTransation (0, selecting);
|
|
|
|
return moveCaretWithTransaction (0, selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretToStartOfLine (bool selecting)
|
|
|
|
{
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition (0.0f, caretPos.getY()), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition (0.0f, caretPos.getY()), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretToEnd (bool selecting)
|
|
|
|
{
|
|
|
|
return moveCaretWithTransation (getTotalNumChars(), selecting);
|
|
|
|
return moveCaretWithTransaction (getTotalNumChars(), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::moveCaretToEndOfLine (bool selecting)
|
|
|
|
{
|
|
|
|
const Rectangle<float> caretPos (getCaretRectangle().toFloat());
|
|
|
|
return moveCaretWithTransation (indexAtPosition ((float) textHolder->getWidth(), caretPos.getY()), selecting);
|
|
|
|
return moveCaretWithTransaction (indexAtPosition ((float) textHolder->getWidth(), caretPos.getY()), selecting);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TextEditor::deleteBackwards (bool moveInWholeWordSteps)
|
|
|
@@ -2128,9 +2083,9 @@ void TextEditor::focusGained (FocusChangeType) |
|
|
|
repaint();
|
|
|
|
updateCaretPosition();
|
|
|
|
|
|
|
|
ComponentPeer* const peer = getPeer();
|
|
|
|
if (peer != nullptr && ! isReadOnly())
|
|
|
|
peer->textInputRequired (getScreenPosition() - peer->getScreenPosition());
|
|
|
|
if (ComponentPeer* const peer = getPeer())
|
|
|
|
if (! isReadOnly())
|
|
|
|
peer->textInputRequired (getScreenPosition() - peer->getScreenPosition());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::focusLost (FocusChangeType)
|
|
|
@@ -2142,8 +2097,7 @@ void TextEditor::focusLost (FocusChangeType) |
|
|
|
|
|
|
|
underlinedSections.clear();
|
|
|
|
|
|
|
|
ComponentPeer* const peer = getPeer();
|
|
|
|
if (peer != nullptr)
|
|
|
|
if (ComponentPeer* const peer = getPeer())
|
|
|
|
peer->dismissPendingTextInput();
|
|
|
|
|
|
|
|
updateCaretPosition();
|
|
|
@@ -2160,14 +2114,10 @@ void TextEditor::resized() |
|
|
|
|
|
|
|
updateTextHolderSize();
|
|
|
|
|
|
|
|
if (! isMultiLine())
|
|
|
|
{
|
|
|
|
scrollToMakeSureCursorIsVisible();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (isMultiLine())
|
|
|
|
updateCaretPosition();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
scrollToMakeSureCursorIsVisible();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::handleCommandMessage (const int commandId)
|
|
|
@@ -2600,8 +2550,3 @@ void TextEditor::coalesceSimilarSections() |
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextEditor::Listener::textEditorTextChanged (TextEditor&) {}
|
|
|
|
void TextEditor::Listener::textEditorReturnKeyPressed (TextEditor&) {}
|
|
|
|
void TextEditor::Listener::textEditorEscapeKeyPressed (TextEditor&) {}
|
|
|
|
void TextEditor::Listener::textEditorFocusLost (TextEditor&) {}
|