diff --git a/extras/Projucer/Builds/LinuxMakefile/Makefile b/extras/Projucer/Builds/LinuxMakefile/Makefile
index cc718ff446..00982105c7 100644
--- a/extras/Projucer/Builds/LinuxMakefile/Makefile
+++ b/extras/Projucer/Builds/LinuxMakefile/Makefile
@@ -37,7 +37,7 @@ ifeq ($(CONFIG),Debug)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
JUCE_TARGET_APP := Projucer
- JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 -std=c++11 $(CFLAGS)
+ JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -g -ggdb -O0 $(CFLAGS)
JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS)
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) $(shell pkg-config --libs freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -ldl -lpthread -lrt $(LDFLAGS)
@@ -58,7 +58,7 @@ ifeq ($(CONFIG),Release)
JUCE_CPPFLAGS_APP := -DJucePlugin_Build_VST=0 -DJucePlugin_Build_VST3=0 -DJucePlugin_Build_AU=0 -DJucePlugin_Build_AUv3=0 -DJucePlugin_Build_RTAS=0 -DJucePlugin_Build_AAX=0 -DJucePlugin_Build_Standalone=0
JUCE_TARGET_APP := Projucer
- JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 -std=c++11 $(CFLAGS)
+ JUCE_CFLAGS += $(JUCE_CPPFLAGS) $(TARGET_ARCH) -O3 $(CFLAGS)
JUCE_CXXFLAGS += $(CXXFLAGS) $(JUCE_CFLAGS) -std=c++11 $(CXXFLAGS)
JUCE_LDFLAGS += $(TARGET_ARCH) -L$(JUCE_BINDIR) -L$(JUCE_LIBDIR) -fvisibility=hidden $(shell pkg-config --libs freetype2 libcurl x11 xext xinerama webkit2gtk-4.0 gtk+-x11-3.0) -ldl -lpthread -lrt $(LDFLAGS)
diff --git a/extras/Projucer/Projucer.jucer b/extras/Projucer/Projucer.jucer
index 09554746e6..58b5ef5c51 100644
--- a/extras/Projucer/Projucer.jucer
+++ b/extras/Projucer/Projucer.jucer
@@ -86,8 +86,8 @@
-
+
diff --git a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp
index e1627f15e6..16880480d6 100644
--- a/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp
+++ b/extras/Projucer/Source/Project Saving/jucer_ProjectExporter.cpp
@@ -350,10 +350,6 @@ void ProjectExporter::addVSTPathsIfPluginOrHost()
void ProjectExporter::addCommonAudioPluginSettings()
{
- if (isLinux()
- && (shouldBuildTargetType (ProjectType::Target::VSTPlugIn) || shouldBuildTargetType (ProjectType::Target::VST3PlugIn)))
- makefileExtraLinkerFlags.add ("-Wl,--no-undefined");
-
if (shouldBuildTargetType (ProjectType::Target::AAXPlugIn))
addAAXFoldersToPath();
diff --git a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
index c2b6820ded..5ed6dfaf64 100644
--- a/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
+++ b/modules/juce_audio_plugin_client/AAX/juce_AAX_Wrapper.cpp
@@ -100,7 +100,11 @@
using namespace juce;
-const int32_t juceChunkType = 'juce';
+#ifndef JucePlugin_AAX_Chunk_Identifier
+ #define JucePlugin_AAX_Chunk_Identifier 'juce'
+#endif
+
+const int32_t juceChunkType = JucePlugin_AAX_Chunk_Identifier;
const int maxAAXChannels = 8;
//==============================================================================
diff --git a/modules/juce_gui_basics/widgets/juce_Slider.cpp b/modules/juce_gui_basics/widgets/juce_Slider.cpp
index bd6b0a268f..5b40afb9c4 100644
--- a/modules/juce_gui_basics/widgets/juce_Slider.cpp
+++ b/modules/juce_gui_basics/widgets/juce_Slider.cpp
@@ -1602,6 +1602,10 @@ void Slider::mouseUp (const MouseEvent&) { pimpl->mouseUp(); }
void Slider::mouseMove (const MouseEvent&) { pimpl->mouseMove(); }
void Slider::mouseExit (const MouseEvent&) { pimpl->mouseExit(); }
+// If popup display is enabled and set to show on mouse hover, this makes sure
+// it is shown when dragging the mouse over a slider and releasing
+void Slider::mouseEnter (const MouseEvent&) { pimpl->mouseMove(); }
+
void Slider::modifierKeysChanged (const ModifierKeys& modifiers)
{
if (isEnabled())
diff --git a/modules/juce_gui_basics/widgets/juce_Slider.h b/modules/juce_gui_basics/widgets/juce_Slider.h
index ae60454c96..ff20d95bd4 100644
--- a/modules/juce_gui_basics/widgets/juce_Slider.h
+++ b/modules/juce_gui_basics/widgets/juce_Slider.h
@@ -910,6 +910,8 @@ public:
void mouseMove (const MouseEvent&) override;
/** @internal */
void mouseExit (const MouseEvent&) override;
+ /** @internal */
+ void mouseEnter (const MouseEvent&) override;
private:
//==============================================================================
diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
index c40956cfe8..2a212ef24f 100644
--- a/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
+++ b/modules/juce_gui_basics/widgets/juce_TextEditor.cpp
@@ -39,7 +39,7 @@ struct TextAtom
bool isWhitespace() const noexcept { return CharacterFunctions::isWhitespace (atomText[0]); }
bool isNewLine() const noexcept { return atomText[0] == '\r' || atomText[0] == '\n'; }
- String getText (const juce_wchar passwordCharacter) const
+ String getText (juce_wchar passwordCharacter) const
{
if (passwordCharacter == 0)
return atomText;
@@ -73,30 +73,29 @@ public:
initialiseAtoms (text, passwordChar);
}
- UniformTextSection (const UniformTextSection& other)
- : font (other.font), colour (other.colour)
- {
- atoms.addCopiesOf (other.atoms);
- }
+ UniformTextSection (const UniformTextSection&) = default;
+ UniformTextSection (UniformTextSection&&) = default;
+ UniformTextSection& operator= (const UniformTextSection&) = delete;
void append (UniformTextSection& other, const juce_wchar passwordChar)
{
- if (other.atoms.size() > 0)
+ if (! other.atoms.isEmpty())
{
int i = 0;
- if (auto* lastAtom = atoms.getLast())
+ if (! atoms.isEmpty())
{
- if (! CharacterFunctions::isWhitespace (lastAtom->atomText.getLastCharacter()))
+ auto& lastAtom = atoms.getReference (atoms.size() - 1);
+
+ if (! CharacterFunctions::isWhitespace (lastAtom.atomText.getLastCharacter()))
{
- auto* first = other.atoms.getUnchecked(0);
+ auto& first = other.atoms.getReference(0);
- if (! CharacterFunctions::isWhitespace (first->atomText[0]))
+ if (! CharacterFunctions::isWhitespace (first.atomText[0]))
{
- lastAtom->atomText += first->atomText;
- lastAtom->numChars = (uint16) (lastAtom->numChars + first->numChars);
- lastAtom->width = font.getStringWidthFloat (lastAtom->getText (passwordChar));
- delete first;
+ lastAtom.atomText += first.atomText;
+ lastAtom.numChars = (uint16) (lastAtom.numChars + first.numChars);
+ lastAtom.width = font.getStringWidthFloat (lastAtom.getText (passwordChar));
++i;
}
}
@@ -106,50 +105,48 @@ public:
while (i < other.atoms.size())
{
- atoms.add (other.atoms.getUnchecked(i));
+ atoms.add (other.atoms.getReference(i));
++i;
}
-
- other.atoms.clear (false);
}
}
- UniformTextSection* split (const int indexToBreakAt, const juce_wchar passwordChar)
+ UniformTextSection* split (int indexToBreakAt, juce_wchar passwordChar)
{
- UniformTextSection* const section2 = new UniformTextSection (String(), font, colour, passwordChar);
+ auto* section2 = new UniformTextSection (String(), font, colour, passwordChar);
int index = 0;
for (int i = 0; i < atoms.size(); ++i)
{
- auto* atom = atoms.getUnchecked(i);
- auto nextIndex = index + atom->numChars;
+ auto& atom = atoms.getReference(i);
+ auto nextIndex = index + atom.numChars;
if (index == indexToBreakAt)
{
for (int j = i; j < atoms.size(); ++j)
section2->atoms.add (atoms.getUnchecked (j));
- atoms.removeRange (i, atoms.size(), false);
+ atoms.removeRange (i, atoms.size());
break;
}
- else if (indexToBreakAt >= index && indexToBreakAt < nextIndex)
- {
- auto* secondAtom = new TextAtom();
- secondAtom->atomText = atom->atomText.substring (indexToBreakAt - index);
- secondAtom->width = font.getStringWidthFloat (secondAtom->getText (passwordChar));
- secondAtom->numChars = (uint16) secondAtom->atomText.length();
+ if (indexToBreakAt >= index && indexToBreakAt < nextIndex)
+ {
+ TextAtom secondAtom;
+ secondAtom.atomText = atom.atomText.substring (indexToBreakAt - index);
+ 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 (passwordChar));
- atom->numChars = (uint16) (indexToBreakAt - index);
+ atom.atomText = atom.atomText.substring (0, indexToBreakAt - index);
+ atom.width = font.getStringWidthFloat (atom.getText (passwordChar));
+ atom.numChars = (uint16) (indexToBreakAt - index);
for (int j = i + 1; j < atoms.size(); ++j)
section2->atoms.add (atoms.getUnchecked (j));
- atoms.removeRange (i + 1, atoms.size(), false);
+ atoms.removeRange (i + 1, atoms.size());
break;
}
@@ -161,27 +158,27 @@ public:
void appendAllText (MemoryOutputStream& mo) const
{
- for (int i = 0; i < atoms.size(); ++i)
- mo << atoms.getUnchecked(i)->atomText;
+ for (auto& atom : atoms)
+ mo << atom.atomText;
}
- void appendSubstring (MemoryOutputStream& mo, const Range range) const
+ void appendSubstring (MemoryOutputStream& mo, Range range) const
{
int index = 0;
- for (auto* atom : atoms)
+ for (auto& atom : atoms)
{
- auto nextIndex = index + atom->numChars;
+ auto nextIndex = index + atom.numChars;
if (range.getStart() < nextIndex)
{
if (range.getEnd() <= index)
break;
- auto r = (range - index).getIntersectionWith (Range (0, (int) atom->numChars));
+ auto r = (range - index).getIntersectionWith ({ 0, (int) atom.numChars });
if (! r.isEmpty())
- mo << atom->atomText.substring (r.getStart(), r.getEnd());
+ mo << atom.atomText.substring (r.getStart(), r.getEnd());
}
index = nextIndex;
@@ -192,8 +189,8 @@ public:
{
int total = 0;
- for (auto* atom : atoms)
- total += atom->numChars;
+ for (auto& atom : atoms)
+ total += atom.numChars;
return total;
}
@@ -204,15 +201,15 @@ public:
{
font = newFont;
- for (auto* atom : atoms)
- atom->width = newFont.getStringWidthFloat (atom->getText (passwordChar));
+ for (auto& atom : atoms)
+ atom.width = newFont.getStringWidthFloat (atom.getText (passwordChar));
}
}
//==============================================================================
Font font;
Colour colour;
- OwnedArray atoms;
+ Array atoms;
private:
void initialiseAtoms (const String& textToParse, const juce_wchar passwordChar)
@@ -262,32 +259,31 @@ private:
}
}
- auto* atom = atoms.add (new TextAtom());
-
- atom->atomText = String (start, numChars);
- atom->width = font.getStringWidthFloat (atom->getText (passwordChar));
- atom->numChars = (uint16) numChars;
+ TextAtom atom;
+ atom.atomText = String (start, numChars);
+ atom.width = font.getStringWidthFloat (atom.getText (passwordChar));
+ atom.numChars = (uint16) numChars;
+ atoms.add (atom);
}
}
- UniformTextSection& operator= (const UniformTextSection&);
JUCE_LEAK_DETECTOR (UniformTextSection)
};
//==============================================================================
-class TextEditor::Iterator
+struct TextEditor::Iterator
{
-public:
- Iterator (const OwnedArray& sectionList,
- float wrapWidth, juce_wchar passwordChar, float spacing)
- : sections (sectionList),
- wordWrapWidth (wrapWidth),
- passwordCharacter (passwordChar),
- lineSpacing (spacing)
+ Iterator (const TextEditor& ed)
+ : sections (ed.sections),
+ justification (ed.justification),
+ justificationWidth (ed.getJustificationWidth()),
+ wordWrapWidth (ed.getWordWrapWidth()),
+ passwordCharacter (ed.passwordCharacter),
+ lineSpacing (ed.lineSpacing)
{
jassert (wordWrapWidth > 0);
- if (sections.size() > 0)
+ if (! sections.isEmpty())
{
currentSection = sections.getUnchecked (sectionIndex);
@@ -296,38 +292,20 @@ public:
}
}
- Iterator (const Iterator& other)
- : 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),
- lineSpacing (other.lineSpacing),
- tempAtom (other.tempAtom)
- {
- }
+ Iterator (const Iterator&) = default;
+ Iterator& operator= (const Iterator&) = delete;
//==============================================================================
bool next()
{
if (atom == &tempAtom)
{
- const int numRemaining = tempAtom.atomText.length() - tempAtom.numChars;
+ auto numRemaining = tempAtom.atomText.length() - tempAtom.numChars;
if (numRemaining > 0)
{
tempAtom.atomText = tempAtom.atomText.substring (tempAtom.numChars);
- atomX = 0;
-
if (tempAtom.numChars > 0)
lineY += lineHeight * lineSpacing;
@@ -345,6 +323,7 @@ public:
{
tempAtom.numChars = (uint16) split;
tempAtom.width = g.getGlyph (split - 1).getRight();
+ atomX = getJustificationOffset (tempAtom.width);
atomRight = atomX + tempAtom.width;
return true;
}
@@ -374,13 +353,13 @@ public:
}
else
{
- auto* lastAtom = currentSection->atoms.getUnchecked (atomIndex);
+ auto& lastAtom = currentSection->atoms.getReference (atomIndex);
- if (! lastAtom->isWhitespace())
+ if (! lastAtom.isWhitespace())
{
// handle the case where the last atom in a section is actually part of the same
// word as the first atom of the next section...
- float right = atomRight + lastAtom->width;
+ float right = atomRight + lastAtom.width;
float lineHeight2 = lineHeight;
float maxDescent2 = maxDescent;
@@ -391,12 +370,12 @@ public:
if (s->atoms.size() == 0)
break;
- auto* nextAtom = s->atoms.getUnchecked (0);
+ auto& nextAtom = s->atoms.getReference (0);
- if (nextAtom->isWhitespace())
+ if (nextAtom.isWhitespace())
break;
- right += nextAtom->width;
+ right += nextAtom.width;
lineHeight2 = jmax (lineHeight2, s->font.getHeight());
maxDescent2 = jmax (maxDescent2, s->font.getDescent());
@@ -426,7 +405,7 @@ public:
beginNewLine();
}
- atom = currentSection->atoms.getUnchecked (atomIndex);
+ atom = &(currentSection->atoms.getReference (atomIndex));
atomRight = atomX + atom->width;
++atomIndex;
@@ -439,22 +418,22 @@ public:
}
else
{
- atomRight = atom->width;
-
- if (shouldWrap (atomRight)) // atom too big to fit on a line, so break it up..
+ if (shouldWrap (atom->width)) // atom too big to fit on a line, so break it up..
{
tempAtom = *atom;
tempAtom.width = 0;
tempAtom.numChars = 0;
atom = &tempAtom;
- if (atomX > 0)
+ if (atomX > justificationOffset)
beginNewLine();
return next();
}
beginNewLine();
+ atomX = justificationOffset;
+ atomRight = atomX + atom->width;
return true;
}
}
@@ -464,20 +443,22 @@ public:
void beginNewLine()
{
- atomX = 0;
lineY += lineHeight * lineSpacing;
+ float lineWidth = 0;
- int tempSectionIndex = sectionIndex;
- int tempAtomIndex = atomIndex;
+ auto tempSectionIndex = sectionIndex;
+ auto tempAtomIndex = atomIndex;
auto* section = sections.getUnchecked (tempSectionIndex);
lineHeight = section->font.getHeight();
maxDescent = section->font.getDescent();
- float x = (atom != nullptr) ? atom->width : 0;
+ float nextLineWidth = (atom != nullptr) ? atom->width : 0.0f;
- while (! shouldWrap (x))
+ while (! shouldWrap (nextLineWidth))
{
+ lineWidth = nextLineWidth;
+
if (tempSectionIndex >= sections.size())
break;
@@ -493,14 +474,13 @@ public:
checkSize = true;
}
- auto* nextAtom = section->atoms.getUnchecked (tempAtomIndex);
-
- if (nextAtom == nullptr)
+ if (! isPositiveAndBelow (tempAtomIndex, section->atoms.size()))
break;
- x += nextAtom->width;
+ auto& nextAtom = section->atoms.getReference (tempAtomIndex);
+ nextLineWidth += nextAtom.width;
- if (shouldWrap (x) || nextAtom->isNewLine())
+ if (shouldWrap (nextLineWidth) || nextAtom.isNewLine())
break;
if (checkSize)
@@ -511,6 +491,20 @@ public:
++tempAtomIndex;
}
+
+ justificationOffset = getJustificationOffset (lineWidth);
+ atomX = justificationOffset;
+ }
+
+ float getJustificationOffset (float lineWidth) const
+ {
+ if (justification.getOnlyHorizontalFlags() == Justification::horizontallyCentred)
+ return jmax (0.0f, (justificationWidth - lineWidth) * 0.5f);
+
+ if (justification.getOnlyHorizontalFlags() == Justification::right)
+ return jmax (0.0f, justificationWidth - lineWidth);
+
+ return 0;
}
//==============================================================================
@@ -535,28 +529,26 @@ public:
}
}
- void addSelection (RectangleList& area, const Range selected) const
+ void addSelection (RectangleList& area, Range selected) const
{
- const float startX = indexToX (selected.getStart());
- const float endX = indexToX (selected.getEnd());
+ auto startX = indexToX (selected.getStart());
+ auto endX = indexToX (selected.getEnd());
area.add (startX, lineY, endX - startX, lineHeight * lineSpacing);
}
- void drawUnderline (Graphics& g, const Range underline, const Colour colour) const
+ void drawUnderline (Graphics& g, Range underline, Colour colour) const
{
- const int startX = roundToInt (indexToX (underline.getStart()));
- const int endX = roundToInt (indexToX (underline.getEnd()));
- const int baselineY = roundToInt (lineY + currentSection->font.getAscent() + 0.5f);
+ auto startX = roundToInt (indexToX (underline.getStart()));
+ auto endX = roundToInt (indexToX (underline.getEnd()));
+ auto baselineY = roundToInt (lineY + currentSection->font.getAscent() + 0.5f);
Graphics::ScopedSaveState state (g);
- g.reduceClipRegion (Rectangle (startX, baselineY, endX - startX, 1));
- g.fillCheckerBoard (Rectangle (endX, baselineY + 1), 3, 1, colour, Colours::transparentBlack);
+ g.reduceClipRegion ({ startX, baselineY, endX - startX, 1 });
+ g.fillCheckerBoard ({ endX, baselineY + 1 }, 3, 1, colour, Colours::transparentBlack);
}
- void drawSelectedText (Graphics& g,
- const Range selected,
- const Colour selectedTextColour) const
+ void drawSelectedText (Graphics& g, Range selected, Colour selectedTextColour) const
{
if (passwordCharacter != 0 || ! atom->isWhitespace())
{
@@ -591,7 +583,7 @@ public:
}
//==============================================================================
- float indexToX (const int indexToFind) const
+ float indexToX (int indexToFind) const
{
if (indexToFind <= indexInText)
return atomX;
@@ -610,7 +602,7 @@ public:
return jmin (atomRight, g.getGlyph (indexToFind - indexInText).getLeft());
}
- int xToIndex (const float xToFind) const
+ int xToIndex (float xToFind) const
{
if (xToFind <= atomX || atom->isNewLine())
return indexInText;
@@ -623,7 +615,7 @@ public:
atom->getText (passwordCharacter),
atomX, 0.0f);
- const int numGlyphs = g.getNumGlyphs();
+ auto numGlyphs = g.getNumGlyphs();
int j;
for (j = 0; j < numGlyphs; ++j)
@@ -638,28 +630,26 @@ public:
}
//==============================================================================
- bool getCharPosition (const int index, float& cx, float& cy, float& lineHeightFound)
+ bool getCharPosition (int index, Point& anchor, float& lineHeightFound)
{
while (next())
{
if (indexInText + atom->numChars > index)
{
- cx = indexToX (index);
- cy = lineY;
+ anchor = { indexToX (index), lineY };
lineHeightFound = lineHeight;
return true;
}
}
- cx = atomX;
- cy = lineY;
+ anchor = { atomX, lineY };
lineHeightFound = lineHeight;
return false;
}
//==============================================================================
int indexInText = 0;
- float lineY = 0, lineHeight = 0, maxDescent = 0;
+ float lineY = 0, justificationOffset = 0, lineHeight = 0, maxDescent = 0;
float atomX = 0, atomRight = 0;
const TextAtom* atom = nullptr;
const UniformTextSection* currentSection = nullptr;
@@ -667,13 +657,12 @@ public:
private:
const OwnedArray& sections;
int sectionIndex = 0, atomIndex = 0;
- const float wordWrapWidth;
+ Justification justification;
+ const float justificationWidth, wordWrapWidth;
const juce_wchar passwordCharacter;
const float lineSpacing;
TextAtom tempAtom;
- Iterator& operator= (const Iterator&) = delete;
-
void moveToEndOfLastAtom()
{
if (atom != nullptr)
@@ -698,16 +687,10 @@ private:
//==============================================================================
-class TextEditor::InsertAction : public UndoableAction
+struct TextEditor::InsertAction : public UndoableAction
{
-public:
- InsertAction (TextEditor& ed,
- const String& newText,
- const int insertPos,
- const Font& newFont,
- const Colour newColour,
- const int oldCaret,
- const int newCaret)
+ InsertAction (TextEditor& ed, const String& newText, int insertPos,
+ const Font& newFont, Colour newColour, int oldCaret, int newCaret)
: owner (ed),
text (newText),
insertIndex (insertPos),
@@ -726,7 +709,7 @@ public:
bool undo() override
{
- owner.remove (Range (insertIndex, insertIndex + text.length()), 0, oldCaretPos);
+ owner.remove ({ insertIndex, insertIndex + text.length() }, 0, oldCaretPos);
return true;
}
@@ -746,13 +729,9 @@ private:
};
//==============================================================================
-class TextEditor::RemoveAction : public UndoableAction
+struct TextEditor::RemoveAction : public UndoableAction
{
-public:
- RemoveAction (TextEditor& ed,
- const Range rangeToRemove,
- const int oldCaret,
- const int newCaret,
+ RemoveAction (TextEditor& ed, Range rangeToRemove, int oldCaret, int newCaret,
const Array& oldSections)
: owner (ed),
range (rangeToRemove),
@@ -795,11 +774,10 @@ private:
};
//==============================================================================
-class TextEditor::TextHolderComponent : public Component,
- public Timer,
- public Value::Listener
+struct TextEditor::TextHolderComponent : public Component,
+ public Timer,
+ public Value::Listener
{
-public:
TextHolderComponent (TextEditor& ed) : owner (ed)
{
setWantsKeyboardFocus (false);
@@ -834,16 +812,14 @@ public:
owner.textWasChangedByValue();
}
-private:
TextEditor& owner;
JUCE_DECLARE_NON_COPYABLE (TextHolderComponent)
};
//==============================================================================
-class TextEditorViewport : public Viewport
+struct TextEditor::TextEditorViewport : public Viewport
{
-public:
TextEditorViewport (TextEditor& ed) : owner (ed) {}
void visibleAreaChanged (const Rectangle&) override
@@ -851,7 +827,7 @@ public:
if (! rentrant) // it's rare, but possible to get into a feedback loop as the viewport's scrollbars
// appear and disappear, causing the wrap width to change.
{
- const float wordWrapWidth = owner.getWordWrapWidth();
+ auto wordWrapWidth = owner.getWordWrapWidth();
if (wordWrapWidth != lastWordWrapWidth)
{
@@ -882,7 +858,7 @@ namespace TextEditorDefs
const int maxActionsPerTransaction = 100;
- static int getCharacterCategory (const juce_wchar character)
+ static int getCharacterCategory (juce_wchar character) noexcept
{
return CharacterFunctions::isLetterOrDigit (character)
? 2 : (CharacterFunctions::isWhitespace (character) ? 0 : 1);
@@ -980,7 +956,7 @@ void TextEditor::setScrollbarsShown (bool shown)
}
}
-void TextEditor::setReadOnly (const bool shouldBeReadOnly)
+void TextEditor::setReadOnly (bool shouldBeReadOnly)
{
if (readOnly != shouldBeReadOnly)
{
@@ -999,26 +975,35 @@ bool TextEditor::isTextInputActive() const
return ! isReadOnly();
}
-void TextEditor::setReturnKeyStartsNewLine (const bool shouldStartNewLine)
+void TextEditor::setReturnKeyStartsNewLine (bool shouldStartNewLine)
{
returnKeyStartsNewLine = shouldStartNewLine;
}
-void TextEditor::setTabKeyUsedAsCharacter (const bool shouldTabKeyBeUsed)
+void TextEditor::setTabKeyUsedAsCharacter (bool shouldTabKeyBeUsed)
{
tabKeyUsed = shouldTabKeyBeUsed;
}
-void TextEditor::setPopupMenuEnabled (const bool b)
+void TextEditor::setPopupMenuEnabled (bool b)
{
popupMenuEnabled = b;
}
-void TextEditor::setSelectAllWhenFocused (const bool b)
+void TextEditor::setSelectAllWhenFocused (bool b)
{
selectAllTextWhenFocused = b;
}
+void TextEditor::setJustification (Justification j)
+{
+ if (justification != j)
+ {
+ justification = j;
+ resized();
+ }
+}
+
//==============================================================================
void TextEditor::setFont (const Font& newFont)
{
@@ -1074,7 +1059,7 @@ void TextEditor::enablementChanged()
repaint();
}
-void TextEditor::setCaretVisible (const bool shouldCaretBeVisible)
+void TextEditor::setCaretVisible (bool shouldCaretBeVisible)
{
if (caretVisible != shouldCaretBeVisible)
{
@@ -1127,7 +1112,7 @@ void TextEditor::setInputFilter (InputFilter* newFilter, bool takeOwnership)
inputFilter.set (newFilter, takeOwnership);
}
-void TextEditor::setInputRestrictions (const int maxLen, const String& chars)
+void TextEditor::setInputRestrictions (int maxLen, const String& chars)
{
setInputFilter (new LengthAndCharacterRestriction (maxLen, chars), true);
}
@@ -1138,7 +1123,7 @@ void TextEditor::setTextToShowWhenEmpty (const String& text, Colour colourToUse)
colourForTextWhenEmpty = colourToUse;
}
-void TextEditor::setPasswordCharacter (const juce_wchar newPasswordCharacter)
+void TextEditor::setPasswordCharacter (juce_wchar newPasswordCharacter)
{
if (passwordCharacter != newPasswordCharacter)
{
@@ -1147,7 +1132,7 @@ void TextEditor::setPasswordCharacter (const juce_wchar newPasswordCharacter)
}
}
-void TextEditor::setScrollBarThickness (const int newThicknessPixels)
+void TextEditor::setScrollBarThickness (int newThicknessPixels)
{
viewport->setScrollBarThickness (newThicknessPixels);
}
@@ -1160,10 +1145,9 @@ void TextEditor::clear()
undoManager.clearUndoHistory();
}
-void TextEditor::setText (const String& newText,
- const bool sendTextChangeMessage)
+void TextEditor::setText (const String& newText, bool sendTextChangeMessage)
{
- const int newLength = newText.length();
+ auto newLength = newText.length();
if (newLength != getTotalNumChars() || getText() != newText)
{
@@ -1173,7 +1157,7 @@ void TextEditor::setText (const String& newText,
textValue = newText;
auto oldCursorPos = caretPosition;
- const bool cursorWasAtEnd = oldCursorPos >= getTotalNumChars();
+ bool cursorWasAtEnd = oldCursorPos >= getTotalNumChars();
clearInternal (nullptr);
insert (newText, 0, currentFont, findColour (textColourId), 0, caretPosition);
@@ -1255,21 +1239,20 @@ void TextEditor::timerCallbackInt()
newTransaction();
}
-void TextEditor::repaintText (const Range range)
+void TextEditor::repaintText (Range range)
{
if (! range.isEmpty())
{
- float x = 0, y = 0, lh = currentFont.getHeight();
-
- const float wordWrapWidth = getWordWrapWidth();
+ auto lh = currentFont.getHeight();
+ auto wordWrapWidth = getWordWrapWidth();
if (wordWrapWidth > 0)
{
- Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing);
-
- i.getCharPosition (range.getStart(), x, y, lh);
+ Point anchor;
+ Iterator i (*this);
+ i.getCharPosition (range.getStart(), anchor, lh);
- auto y1 = (int) y;
+ auto y1 = (int) anchor.y;
int y2;
if (range.getEnd() >= getTotalNumChars())
@@ -1278,8 +1261,8 @@ void TextEditor::repaintText (const Range range)
}
else
{
- i.getCharPosition (range.getEnd(), x, y, lh);
- y2 = (int) (y + lh * 2.0f);
+ i.getCharPosition (range.getEnd(), anchor, lh);
+ y2 = (int) (anchor.y + lh * 2.0f);
}
textHolder->repaint (0, y1, textHolder->getWidth(), y2 - y1);
@@ -1316,7 +1299,7 @@ void TextEditor::setCaretPosition (const int newIndex)
void TextEditor::moveCaretToEnd()
{
- moveCaretTo (std::numeric_limits::max(), false);
+ setCaretPosition (std::numeric_limits::max());
}
void TextEditor::scrollEditorToPositionCaret (const int desiredCaretX,
@@ -1326,8 +1309,8 @@ void TextEditor::scrollEditorToPositionCaret (const int desiredCaretX,
updateCaretPosition();
auto caretPos = getCaretRectangle();
- int vx = caretPos.getX() - desiredCaretX;
- int vy = caretPos.getY() - desiredCaretY;
+ auto vx = caretPos.getX() - desiredCaretX;
+ auto vy = caretPos.getY() - desiredCaretY;
if (desiredCaretX < jmax (1, proportionOfWidth (0.05f)))
vx += desiredCaretX - proportionOfWidth (0.2f);
@@ -1355,11 +1338,11 @@ void TextEditor::scrollEditorToPositionCaret (const int desiredCaretX,
Rectangle TextEditor::getCaretRectangle()
{
- float cursorX, cursorY;
- float cursorHeight = currentFont.getHeight(); // (in case the text is empty and the call below doesn't set this value)
- getCharPosition (caretPosition, cursorX, cursorY, cursorHeight);
+ Point anchor;
+ auto cursorHeight = currentFont.getHeight(); // (in case the text is empty and the call below doesn't set this value)
+ getCharPosition (caretPosition, anchor, cursorHeight);
- return { roundToInt (cursorX), roundToInt (cursorY), 2, roundToInt (cursorHeight) };
+ return { roundToInt (anchor.x), roundToInt (anchor.y), 2, roundToInt (cursorHeight) };
}
//==============================================================================
@@ -1367,26 +1350,27 @@ enum { rightEdgeSpace = 2 };
float TextEditor::getWordWrapWidth() const
{
- return wordWrap ? (float) (viewport->getMaximumVisibleWidth() - (leftIndent + rightEdgeSpace + 1))
+ return wordWrap ? getJustificationWidth()
: std::numeric_limits::max();
}
-void TextEditor::updateTextHolderSize()
+float TextEditor::getJustificationWidth() const
{
- const float wordWrapWidth = getWordWrapWidth();
+ return (float) (viewport->getMaximumVisibleWidth() - (leftIndent + rightEdgeSpace + 1));
+}
- if (wordWrapWidth > 0)
+void TextEditor::updateTextHolderSize()
+{
+ if (getWordWrapWidth() > 0)
{
- float maxWidth = 0.0f;
-
- Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing);
+ float maxWidth = getJustificationWidth();
+ Iterator i (*this);
while (i.next())
maxWidth = jmax (maxWidth, i.atomRight);
- const int w = leftIndent + roundToInt (maxWidth);
- const int h = topIndent + roundToInt (jmax (i.lineY + i.lineHeight,
- currentFont.getHeight()));
+ auto w = leftIndent + roundToInt (maxWidth);
+ auto h = topIndent + roundToInt (jmax (i.lineY + i.lineHeight, currentFont.getHeight()));
textHolder->setSize (w + rightEdgeSpace, h + 1); // (allows a bit of space for the cursor to be at the right-hand-edge)
}
@@ -1395,7 +1379,7 @@ void TextEditor::updateTextHolderSize()
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 (int newLeftIndent, int newTopIndent)
{
leftIndent = newLeftIndent;
topIndent = newTopIndent;
@@ -1567,15 +1551,12 @@ void TextEditor::cut()
//==============================================================================
void TextEditor::drawContent (Graphics& g)
{
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
+ if (getWordWrapWidth() > 0)
{
g.setOrigin (leftIndent, topIndent);
auto clip = g.getClipBounds();
Colour selectedTextColour;
-
- Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing);
+ Iterator i (*this);
if (! selection.isEmpty())
{
@@ -1585,7 +1566,7 @@ void TextEditor::drawContent (Graphics& g)
while (i2.next() && i2.lineY < clip.getBottom())
{
if (i2.lineY + i2.lineHeight >= clip.getY()
- && selection.intersects (Range (i2.indexInText, i2.indexInText + i2.atom->numChars)))
+ && selection.intersects ({ i2.indexInText, i2.indexInText + i2.atom->numChars }))
{
i2.addSelection (selectionArea, selection);
}
@@ -1603,7 +1584,7 @@ void TextEditor::drawContent (Graphics& g)
{
if (i.lineY + i.lineHeight >= clip.getY())
{
- if (selection.intersects (Range (i.indexInText, i.indexInText + i.atom->numChars)))
+ if (selection.intersects ({ i.indexInText, i.indexInText + i.atom->numChars }))
{
i.drawSelectedText (g, selection, selectedTextColour);
lastSection = nullptr;
@@ -1615,16 +1596,14 @@ void TextEditor::drawContent (Graphics& g)
}
}
- for (int j = underlinedSections.size(); --j >= 0;)
+ for (auto& underlinedSection : underlinedSections)
{
- const Range underlinedSection = underlinedSections.getReference (j);
-
- Iterator i2 (sections, wordWrapWidth, passwordCharacter, lineSpacing);
+ Iterator i2 (*this);
while (i2.next() && i2.lineY < clip.getBottom())
{
if (i2.lineY + i2.lineHeight >= clip.getY()
- && underlinedSection.intersects (Range (i2.indexInText, i2.indexInText + i2.atom->numChars)))
+ && underlinedSection.intersects ({ i2.indexInText, i2.indexInText + i2.atom->numChars }))
{
i2.drawUnderline (g, underlinedSection, findColour (textColourId));
}
@@ -1764,8 +1743,9 @@ void TextEditor::mouseDoubleClick (const MouseEvent& e)
while (tokenEnd < totalLength)
{
+ auto c = t[tokenEnd];
+
// (note the slight bodge here - it's because iswalnum only checks for alphabetic chars in the current locale)
- const juce_wchar c = t [tokenEnd];
if (CharacterFunctions::isLetterOrDigit (c) || c > 128)
++tokenEnd;
else
@@ -1776,8 +1756,9 @@ void TextEditor::mouseDoubleClick (const MouseEvent& e)
while (tokenStart > 0)
{
+ auto c = t[tokenStart - 1];
+
// (note the slight bodge here - it's because iswalnum only checks for alphabetic chars in the current locale)
- const juce_wchar c = t [tokenStart - 1];
if (CharacterFunctions::isLetterOrDigit (c) || c > 128)
--tokenStart;
else
@@ -1788,7 +1769,8 @@ void TextEditor::mouseDoubleClick (const MouseEvent& e)
{
while (tokenEnd < totalLength)
{
- const juce_wchar c = t [tokenEnd];
+ auto c = t[tokenEnd];
+
if (c != '\r' && c != '\n')
++tokenEnd;
else
@@ -1797,7 +1779,8 @@ void TextEditor::mouseDoubleClick (const MouseEvent& e)
while (tokenStart > 0)
{
- const juce_wchar c = t [tokenStart - 1];
+ auto c = t[tokenStart - 1];
+
if (c != '\r' && c != '\n')
--tokenStart;
else
@@ -1826,7 +1809,7 @@ bool TextEditor::moveCaretWithTransaction (const int newPos, const bool selectin
bool TextEditor::moveCaretLeft (bool moveInWholeWordSteps, bool selecting)
{
- int pos = getCaretPosition();
+ auto pos = getCaretPosition();
if (moveInWholeWordSteps)
pos = findWordBreakBefore (pos);
@@ -1838,7 +1821,7 @@ bool TextEditor::moveCaretLeft (bool moveInWholeWordSteps, bool selecting)
bool TextEditor::moveCaretRight (bool moveInWholeWordSteps, bool selecting)
{
- int pos = getCaretPosition();
+ auto pos = getCaretPosition();
if (moveInWholeWordSteps)
pos = findWordBreakAfter (pos);
@@ -1929,7 +1912,7 @@ bool TextEditor::deleteBackwards (bool moveInWholeWordSteps)
if (moveInWholeWordSteps)
moveCaretTo (findWordBreakBefore (getCaretPosition()), true);
else if (selection.isEmpty() && selection.getStart() > 0)
- selection = Range (selection.getEnd() - 1, selection.getEnd());
+ selection = { selection.getEnd() - 1, selection.getEnd() };
cut();
return true;
@@ -1938,7 +1921,7 @@ bool TextEditor::deleteBackwards (bool moveInWholeWordSteps)
bool TextEditor::deleteForwards (bool /*moveInWholeWordSteps*/)
{
if (selection.isEmpty() && selection.getStart() < getTotalNumChars())
- selection = Range (selection.getStart(), selection.getStart() + 1);
+ selection = { selection.getStart(), selection.getStart() + 1 };
cut();
return true;
@@ -1993,7 +1976,9 @@ bool TextEditor::keyPressed (const KeyPress& key)
newTransaction();
if (returnKeyStartsNewLine)
+ {
insertTextAtCaret ("\n");
+ }
else
{
returnPressed();
@@ -2136,15 +2121,11 @@ UndoManager* TextEditor::getUndoManager() noexcept
void TextEditor::clearInternal (UndoManager* const um)
{
- remove (Range (0, getTotalNumChars()), um, caretPosition);
+ remove ({ 0, getTotalNumChars() }, um, caretPosition);
}
-void TextEditor::insert (const String& text,
- const int insertIndex,
- const Font& font,
- const Colour colour,
- UndoManager* const um,
- const int caretPositionToMoveTo)
+void TextEditor::insert (const String& text, int insertIndex, const Font& font,
+ Colour colour, UndoManager* um, int caretPositionToMoveTo)
{
if (text.isNotEmpty())
{
@@ -2158,8 +2139,8 @@ void TextEditor::insert (const String& text,
}
else
{
- repaintText (Range (insertIndex, getTotalNumChars())); // must do this before and after changing the data, in case
- // a line gets moved due to word wrap
+ repaintText ({ insertIndex, getTotalNumChars() }); // must do this before and after changing the data, in case
+ // a line gets moved due to word wrap
int index = 0;
int nextIndex = 0;
@@ -2173,7 +2154,8 @@ void TextEditor::insert (const String& text,
sections.insert (i, new UniformTextSection (text, font, colour, passwordCharacter));
break;
}
- else if (insertIndex > index && insertIndex < nextIndex)
+
+ if (insertIndex > index && insertIndex < nextIndex)
{
splitSection (i, insertIndex - index);
sections.insert (i + 1, new UniformTextSection (text, font, colour, passwordCharacter));
@@ -2193,12 +2175,12 @@ void TextEditor::insert (const String& text,
updateTextHolderSize();
moveCaretTo (caretPositionToMoveTo, false);
- repaintText (Range (insertIndex, getTotalNumChars()));
+ repaintText ({ insertIndex, getTotalNumChars() });
}
}
}
-void TextEditor::reinsert (const int insertIndex, const OwnedArray& sectionsToInsert)
+void TextEditor::reinsert (int insertIndex, const OwnedArray& sectionsToInsert)
{
int index = 0;
int nextIndex = 0;
@@ -2214,7 +2196,8 @@ void TextEditor::reinsert (const int insertIndex, const OwnedArray index && insertIndex < nextIndex)
+
+ if (insertIndex > index && insertIndex < nextIndex)
{
splitSection (i, insertIndex - index);
@@ -2228,10 +2211,8 @@ void TextEditor::reinsert (const int insertIndex, const OwnedArray range, UndoManager* const um, const int care
for (int i = 0; i < sections.size(); ++i)
{
- const int nextIndex = index + sections.getUnchecked(i)->getTotalLength();
+ auto nextIndex = index + sections.getUnchecked(i)->getTotalLength();
if (range.getStart() > index && range.getStart() < nextIndex)
{
@@ -2273,12 +2254,11 @@ void TextEditor::remove (Range range, UndoManager* const um, const int care
{
Array removedSections;
- for (int i = 0; i < sections.size(); ++i)
+ for (auto* section : sections)
{
if (range.getEnd() <= range.getStart())
break;
- auto* section = sections.getUnchecked (i);
auto nextIndex = index + section->getTotalLength();
if (range.getStart() <= index && range.getEnd() >= nextIndex)
@@ -2300,8 +2280,7 @@ void TextEditor::remove (Range range, UndoManager* const um, const int care
for (int i = 0; i < sections.size(); ++i)
{
auto* section = sections.getUnchecked (i);
-
- const int nextIndex = index + section->getTotalLength();
+ auto nextIndex = index + section->getTotalLength();
if (remainingRange.getStart() <= index && remainingRange.getEnd() >= nextIndex)
{
@@ -2325,7 +2304,7 @@ void TextEditor::remove (Range range, UndoManager* const um, const int care
moveCaretTo (caretPositionToMoveTo, false);
- repaintText (Range (range.getStart(), getTotalNumChars()));
+ repaintText ({ range.getStart(), getTotalNumChars() });
}
}
}
@@ -2336,8 +2315,8 @@ String TextEditor::getText() const
MemoryOutputStream mo;
mo.preallocate ((size_t) getTotalNumChars());
- for (int i = 0; i < sections.size(); ++i)
- sections.getUnchecked (i)->appendAllText (mo);
+ for (auto* s : sections)
+ s->appendAllText (mo);
return mo.toUTF8();
}
@@ -2352,9 +2331,8 @@ String TextEditor::getTextInRange (const Range& range) const
int index = 0;
- for (int i = 0; i < sections.size(); ++i)
+ for (auto* s : sections)
{
- auto* s = sections.getUnchecked (i);
auto nextIndex = index + s->getTotalLength();
if (range.getStart() < nextIndex)
@@ -2382,8 +2360,8 @@ int TextEditor::getTotalNumChars() const
{
totalNumChars = 0;
- for (int i = sections.size(); --i >= 0;)
- totalNumChars += sections.getUnchecked (i)->getTotalLength();
+ for (auto* s : sections)
+ totalNumChars += s->getTotalLength();
}
return totalNumChars;
@@ -2394,32 +2372,34 @@ bool TextEditor::isEmpty() const
return getTotalNumChars() == 0;
}
-void TextEditor::getCharPosition (const int index, float& cx, float& cy, float& lineHeight) const
+void TextEditor::getCharPosition (int index, Point& anchor, float& lineHeight) const
{
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0 && sections.size() > 0)
+ if (getWordWrapWidth() <= 0)
{
- Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing);
-
- i.getCharPosition (index, cx, cy, lineHeight);
+ anchor = {};
+ lineHeight = currentFont.getHeight();
}
else
{
- cx = cy = 0;
- lineHeight = currentFont.getHeight();
+ Iterator i (*this);
+
+ if (sections.isEmpty())
+ {
+ anchor = { i.getJustificationOffset (0), 0 };
+ lineHeight = currentFont.getHeight();
+ }
+ else
+ {
+ i.getCharPosition (index, anchor, lineHeight);
+ }
}
}
int TextEditor::indexAtPosition (const float x, const float y)
{
- const float wordWrapWidth = getWordWrapWidth();
-
- if (wordWrapWidth > 0)
+ if (getWordWrapWidth() > 0)
{
- Iterator i (sections, wordWrapWidth, passwordCharacter, lineSpacing);
-
- while (i.next())
+ for (Iterator i (*this); i.next();)
{
if (i.lineY + i.lineHeight > y)
{
@@ -2441,14 +2421,14 @@ int TextEditor::indexAtPosition (const float x, const float y)
//==============================================================================
int TextEditor::findWordBreakAfter (const int position) const
{
- auto t = getTextInRange (Range (position, position + 512));
+ auto t = getTextInRange ({ position, position + 512 });
auto totalLength = t.length();
int i = 0;
while (i < totalLength && CharacterFunctions::isWhitespace (t[i]))
++i;
- const int type = TextEditorDefs::getCharacterCategory (t[i]);
+ auto type = TextEditorDefs::getCharacterCategory (t[i]);
while (i < totalLength && type == TextEditorDefs::getCharacterCategory (t[i]))
++i;
@@ -2465,7 +2445,7 @@ int TextEditor::findWordBreakBefore (const int position) const
return 0;
auto startOfBuffer = jmax (0, position - 512);
- auto t = getTextInRange (Range (startOfBuffer, position));
+ auto t = getTextInRange ({ startOfBuffer, position });
int i = position - startOfBuffer;
diff --git a/modules/juce_gui_basics/widgets/juce_TextEditor.h b/modules/juce_gui_basics/widgets/juce_TextEditor.h
index 7077d57c04..3315c583c3 100644
--- a/modules/juce_gui_basics/widgets/juce_TextEditor.h
+++ b/modules/juce_gui_basics/widgets/juce_TextEditor.h
@@ -475,8 +475,10 @@ public:
*/
void setScrollToShowCursor (bool shouldScrollToShowCaret);
- /** Sets the line spacing of the TextEditor.
+ /** Modifies the horizontal justification of the text within the editor window. */
+ void setJustification (Justification newJustification);
+ /** Sets the line spacing of the TextEditor.
The default (and minimum) value is 1.0 and values > 1.0 will increase the line spacing as a
multiple of the line height e.g. for double-spacing call this method with an argument of 2.0.
*/
@@ -680,17 +682,17 @@ protected:
private:
//==============================================================================
- class Iterator;
JUCE_PUBLIC_IN_DLL_BUILD (class UniformTextSection)
- class TextHolderComponent;
- class InsertAction;
- class RemoveAction;
- friend class InsertAction;
- friend class RemoveAction;
+ struct Iterator;
+ struct TextHolderComponent;
+ struct TextEditorViewport;
+ struct InsertAction;
+ struct RemoveAction;
ScopedPointer viewport;
TextHolderComponent* textHolder;
BorderSize borderSize { 1, 1, 1, 3 };
+ Justification justification { Justification::left };
bool readOnly = false;
bool caretVisible = true;
@@ -743,10 +745,10 @@ private:
void coalesceSimilarSections();
void splitSection (int sectionIndex, int charToSplitAt);
void clearInternal (UndoManager*);
- void insert (const String&, int insertIndex, const Font&, const Colour, UndoManager*, int newCaretPos);
+ void insert (const String&, int insertIndex, const Font&, Colour, UndoManager*, int newCaretPos);
void reinsert (int insertIndex, const OwnedArray&);
- void remove (Range range, UndoManager*, int caretPositionToMoveTo);
- void getCharPosition (int index, float& x, float& y, float& lineHeight) const;
+ void remove (Range, UndoManager*, int caretPositionToMoveTo);
+ void getCharPosition (int index, Point&, float& lineHeight) const;
void updateCaretPosition();
void updateValueFromText();
void textWasChangedByValue();
@@ -754,11 +756,10 @@ private:
int findWordBreakAfter (int position) const;
int findWordBreakBefore (int position) const;
bool moveCaretWithTransaction (int newPos, bool selecting);
- friend class TextHolderComponent;
- friend class TextEditorViewport;
void drawContent (Graphics&);
void updateTextHolderSize();
float getWordWrapWidth() const;
+ float getJustificationWidth() const;
void timerCallbackInt();
void repaintText (Range);
void scrollByLines (int deltaLines);