Browse Source

Minor optimisations. New method OwnedArray::insertArray(). Changed some CodeDocument inner class constructors to use references rather than pointers.

tags/2021-05-28
jules 13 years ago
parent
commit
d4ae8f3d55
8 changed files with 230 additions and 229 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -1
      extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp
  3. +2
    -2
      modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp
  4. +3
    -3
      modules/juce_core/containers/juce_Array.h
  5. +40
    -0
      modules/juce_core/containers/juce_OwnedArray.h
  6. +123
    -146
      modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp
  7. +15
    -16
      modules/juce_gui_extra/code_editor/juce_CodeDocument.h
  8. +45
    -61
      modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp

+ 1
- 0
.gitignore View File

@@ -15,6 +15,7 @@
*.manifest.res
*.o
*.d
*.sdf
xcuserdata
contents.xcworkspacedata
.DS_Store


+ 1
- 1
extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp View File

@@ -142,7 +142,7 @@ void SourceCodeEditor::highlightLine (int lineNum, int characterIndex)
editor->getDocument().getNumLines() - editor->getNumLinesOnScreen())));
}
editor->moveCaretTo (CodeDocument::Position (&editor->getDocument(), lineNum - 1, characterIndex), false);
editor->moveCaretTo (CodeDocument::Position (editor->getDocument(), lineNum - 1, characterIndex), false);
}
void SourceCodeEditor::resized()


+ 2
- 2
modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp View File

@@ -135,10 +135,10 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
for (int m = info.numSamples; --m >= 0;)
{
const float alpha = (float) subSampleOffset;
const float invAlpha = 1.0f - alpha;
for (int channel = 0; channel < channelsToProcess; ++channel)
*destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha;
*destBuffers[channel]++ = srcBuffers[channel][bufferPos]
+ alpha * (srcBuffers[channel][nextPos] - srcBuffers[channel][bufferPos]);
subSampleOffset += localRatio;


+ 3
- 3
modules/juce_core/containers/juce_Array.h View File

@@ -460,17 +460,17 @@ public:
{
const ScopedLockType lock (getLock());
data.ensureAllocatedSize (numUsed + numberOfElements);
ElementType* insertPos;
ElementType* insertPos = data.elements;
if (isPositiveAndBelow (indexToInsertAt, numUsed))
{
insertPos = data.elements + indexToInsertAt;
insertPos += indexToInsertAt;
const int numberToMove = numUsed - indexToInsertAt;
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType));
}
else
{
insertPos = data.elements + numUsed;
insertPos += numUsed;
}
numUsed += numberOfElements;


+ 40
- 0
modules/juce_core/containers/juce_OwnedArray.h View File

@@ -292,6 +292,46 @@ public:
}
}
/** Inserts an array of values into this array at a given position.
If the index is less than 0 or greater than the size of the array, the
new elements will be added to the end of the array.
Otherwise, they will be inserted into the array, moving all the later elements
along to make room.
@param indexToInsertAt the index at which the first new element should be inserted
@param newObjects the new values to add to the array
@param numberOfElements how many items are in the array
@see insert, add, addSorted, set
*/
void insertArray (int indexToInsertAt,
ObjectClass* const* newObjects,
int numberOfElements)
{
if (numberOfElements > 0)
{
const ScopedLockType lock (getLock());
data.ensureAllocatedSize (numUsed + numberOfElements);
ObjectClass** insertPos = data.elements;
if (isPositiveAndBelow (indexToInsertAt, numUsed))
{
insertPos += indexToInsertAt;
const int numberToMove = numUsed - indexToInsertAt;
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ObjectClass*));
}
else
{
insertPos += numUsed;
}
numUsed += numberOfElements;
while (--numberOfElements >= 0)
*insertPos++ = *newObjects++;
}
}
/** Appends a new object at the end of the array as long as the array doesn't
already contain it.


+ 123
- 146
modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp View File

@@ -123,15 +123,15 @@ public:
};
//==============================================================================
CodeDocument::Iterator::Iterator (CodeDocument* const document_)
: document (document_),
CodeDocument::Iterator::Iterator (const CodeDocument& document_) noexcept
: document (&document_),
charPointer (nullptr),
line (0),
position (0)
{
}
CodeDocument::Iterator::Iterator (const CodeDocument::Iterator& other)
CodeDocument::Iterator::Iterator (const CodeDocument::Iterator& other) noexcept
: document (other.document),
charPointer (other.charPointer),
line (other.line),
@@ -153,13 +153,13 @@ CodeDocument::Iterator::~Iterator() noexcept
{
}
juce_wchar CodeDocument::Iterator::nextChar()
juce_wchar CodeDocument::Iterator::nextChar() noexcept
{
for (;;)
{
if (charPointer.getAddress() == nullptr)
{
CodeDocumentLine* const l = document->lines[line];
const CodeDocumentLine* const l = document->lines[line];
if (l == nullptr)
return 0;
@@ -182,16 +182,16 @@ juce_wchar CodeDocument::Iterator::nextChar()
}
}
void CodeDocument::Iterator::skip()
void CodeDocument::Iterator::skip() noexcept
{
nextChar();
}
void CodeDocument::Iterator::skipToEndOfLine()
void CodeDocument::Iterator::skipToEndOfLine() noexcept
{
if (charPointer.getAddress() == nullptr)
{
CodeDocumentLine* const l = document->lines[line];
const CodeDocumentLine* const l = document->lines[line];
if (l == nullptr)
return;
@@ -204,11 +204,11 @@ void CodeDocument::Iterator::skipToEndOfLine()
charPointer = nullptr;
}
juce_wchar CodeDocument::Iterator::peekNextChar() const
juce_wchar CodeDocument::Iterator::peekNextChar() const noexcept
{
if (charPointer.getAddress() == nullptr)
{
CodeDocumentLine* const l = document->lines[line];
const CodeDocumentLine* const l = document->lines[line];
if (l == nullptr)
return 0;
@@ -221,11 +221,11 @@ juce_wchar CodeDocument::Iterator::peekNextChar() const
if (c != 0)
return c;
CodeDocumentLine* const l = document->lines [line + 1];
const CodeDocumentLine* const l = document->lines [line + 1];
return l == nullptr ? 0 : l->line[0];
}
void CodeDocument::Iterator::skipWhitespace()
void CodeDocument::Iterator::skipWhitespace() noexcept
{
while (CharacterFunctions::isWhitespace (peekNextChar()))
skip();
@@ -238,23 +238,22 @@ bool CodeDocument::Iterator::isEOF() const noexcept
//==============================================================================
CodeDocument::Position::Position() noexcept
: owner (0), characterPos (0), line (0),
: owner (nullptr), characterPos (0), line (0),
indexInLine (0), positionMaintained (false)
{
}
CodeDocument::Position::Position (const CodeDocument* const ownerDocument,
CodeDocument::Position::Position (const CodeDocument& ownerDocument,
const int line_, const int indexInLine_) noexcept
: owner (const_cast <CodeDocument*> (ownerDocument)),
: owner (const_cast <CodeDocument*> (&ownerDocument)),
characterPos (0), line (line_),
indexInLine (indexInLine_), positionMaintained (false)
{
setLineAndIndex (line_, indexInLine_);
}
CodeDocument::Position::Position (const CodeDocument* const ownerDocument,
const int characterPos_) noexcept
: owner (const_cast <CodeDocument*> (ownerDocument)),
CodeDocument::Position::Position (const CodeDocument& ownerDocument, const int characterPos_) noexcept
: owner (const_cast <CodeDocument*> (&ownerDocument)),
positionMaintained (false)
{
setPosition (characterPos_);
@@ -324,25 +323,22 @@ void CodeDocument::Position::setLineAndIndex (const int newLineNum, const int ne
{
line = owner->lines.size() - 1;
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
jassert (l != nullptr);
indexInLine = l->lineLengthWithoutNewLines;
characterPos = l->lineStartInFile + indexInLine;
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
indexInLine = l.lineLengthWithoutNewLines;
characterPos = l.lineStartInFile + indexInLine;
}
else
{
line = jmax (0, newLineNum);
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
jassert (l != nullptr);
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
if (l->lineLengthWithoutNewLines > 0)
indexInLine = jlimit (0, l->lineLengthWithoutNewLines, newIndexInLine);
if (l.lineLengthWithoutNewLines > 0)
indexInLine = jlimit (0, l.lineLengthWithoutNewLines, newIndexInLine);
else
indexInLine = 0;
characterPos = l->lineStartInFile + indexInLine;
characterPos = l.lineStartInFile + indexInLine;
}
}
}
@@ -366,15 +362,14 @@ void CodeDocument::Position::setPosition (const int newPosition)
{
for (int i = lineStart; i < lineEnd; ++i)
{
CodeDocumentLine* const l = owner->lines.getUnchecked (i);
int index = newPosition - l->lineStartInFile;
const CodeDocumentLine& l = *owner->lines.getUnchecked (i);
const int index = newPosition - l.lineStartInFile;
if (index >= 0 && (index < l->lineLength || i == lineEnd - 1))
if (index >= 0 && (index < l.lineLength || i == lineEnd - 1))
{
line = i;
indexInLine = jmin (l->lineLengthWithoutNewLines, index);
characterPos = l->lineStartInFile + indexInLine;
indexInLine = jmin (l.lineLengthWithoutNewLines, index);
characterPos = l.lineStartInFile + indexInLine;
}
}
@@ -383,9 +378,8 @@ void CodeDocument::Position::setPosition (const int newPosition)
else
{
const int midIndex = (lineStart + lineEnd + 1) / 2;
CodeDocumentLine* const mid = owner->lines.getUnchecked (midIndex);
if (newPosition >= mid->lineStartInFile)
if (newPosition >= owner->lines.getUnchecked (midIndex)->lineStartInFile)
lineStart = midIndex;
else
lineEnd = midIndex;
@@ -405,9 +399,10 @@ void CodeDocument::Position::moveBy (int characterDelta)
// If moving right, make sure we don't get stuck between the \r and \n characters..
if (line < owner->lines.size())
{
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
if (indexInLine + characterDelta < l->lineLength
&& indexInLine + characterDelta >= l->lineLengthWithoutNewLines + 1)
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
if (indexInLine + characterDelta < l.lineLength
&& indexInLine + characterDelta >= l.lineLengthWithoutNewLines + 1)
++characterDelta;
}
}
@@ -415,21 +410,21 @@ void CodeDocument::Position::moveBy (int characterDelta)
setPosition (characterPos + characterDelta);
}
const CodeDocument::Position CodeDocument::Position::movedBy (const int characterDelta) const
CodeDocument::Position CodeDocument::Position::movedBy (const int characterDelta) const
{
CodeDocument::Position p (*this);
p.moveBy (characterDelta);
return p;
}
const CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLines) const
CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLines) const
{
CodeDocument::Position p (*this);
p.setLineAndIndex (getLineNumber() + deltaLines, getIndexInLine());
return p;
}
const juce_wchar CodeDocument::Position::getCharacter() const
juce_wchar CodeDocument::Position::getCharacter() const
{
const CodeDocumentLine* const l = owner->lines [line];
return l == nullptr ? 0 : l->line [getIndexInLine()];
@@ -480,8 +475,8 @@ CodeDocument::~CodeDocument()
String CodeDocument::getAllContent() const
{
return getTextBetween (Position (this, 0),
Position (this, lines.size(), 0));
return getTextBetween (Position (*this, 0),
Position (*this, lines.size(), 0));
}
String CodeDocument::getTextBetween (const Position& start, const Position& end) const
@@ -505,22 +500,22 @@ String CodeDocument::getTextBetween (const Position& start, const Position& end)
for (int i = jmax (0, startLine); i <= maxLine; ++i)
{
const CodeDocumentLine* line = lines.getUnchecked(i);
int len = line->lineLength;
const CodeDocumentLine& line = *lines.getUnchecked(i);
int len = line.lineLength;
if (i == startLine)
{
const int index = start.getIndexInLine();
mo << line->line.substring (index, len);
mo << line.line.substring (index, len);
}
else if (i == endLine)
{
len = end.getIndexInLine();
mo << line->line.substring (0, len);
mo << line.line.substring (0, len);
}
else
{
mo << line->line;
mo << line.line;
}
}
@@ -736,20 +731,13 @@ void CodeDocument::checkLastLineStatus()
}
//==============================================================================
void CodeDocument::addListener (CodeDocument::Listener* const listener) noexcept
{
listeners.add (listener);
}
void CodeDocument::removeListener (CodeDocument::Listener* const listener) noexcept
{
listeners.remove (listener);
}
void CodeDocument::addListener (CodeDocument::Listener* const l) noexcept { listeners.add (l); }
void CodeDocument::removeListener (CodeDocument::Listener* const l) noexcept { listeners.remove (l); }
void CodeDocument::sendListenerChangeMessage (const int startLine, const int endLine)
{
Position startPos (this, startLine, 0);
Position endPos (this, endLine, 0);
Position startPos (*this, startLine, 0);
Position endPos (*this, endLine, 0);
listeners.call (&CodeDocument::Listener::codeDocumentChanged, startPos, endPos);
}
@@ -758,10 +746,8 @@ void CodeDocument::sendListenerChangeMessage (const int startLine, const int end
class CodeDocumentInsertAction : public UndoableAction
{
public:
CodeDocumentInsertAction (CodeDocument& owner_, const String& text_, const int insertPos_) noexcept
: owner (owner_),
text (text_),
insertPos (insertPos_)
CodeDocumentInsertAction (CodeDocument& doc, const String& t, const int pos) noexcept
: owner (doc), text (t), insertPos (pos)
{
}
@@ -784,77 +770,72 @@ public:
private:
CodeDocument& owner;
const String text;
int insertPos;
const int insertPos;
JUCE_DECLARE_NON_COPYABLE (CodeDocumentInsertAction);
};
void CodeDocument::insert (const String& text, const int insertPos, const bool undoable)
{
if (text.isEmpty())
return;
if (undoable)
if (text.isNotEmpty())
{
undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos));
}
else
{
Position pos (this, insertPos);
const int firstAffectedLine = pos.getLineNumber();
int lastAffectedLine = firstAffectedLine + 1;
CodeDocumentLine* const firstLine = lines [firstAffectedLine];
String textInsideOriginalLine (text);
if (firstLine != nullptr)
if (undoable)
{
const int index = pos.getIndexInLine();
textInsideOriginalLine = firstLine->line.substring (0, index)
+ textInsideOriginalLine
+ firstLine->line.substring (index);
undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos));
}
else
{
Position pos (*this, insertPos);
const int firstAffectedLine = pos.getLineNumber();
int lastAffectedLine = firstAffectedLine + 1;
maximumLineLength = -1;
Array <CodeDocumentLine*> newLines;
CodeDocumentLine::createLines (newLines, textInsideOriginalLine);
jassert (newLines.size() > 0);
CodeDocumentLine* const firstLine = lines [firstAffectedLine];
String textInsideOriginalLine (text);
CodeDocumentLine* const newFirstLine = newLines.getUnchecked (0);
newFirstLine->lineStartInFile = firstLine != nullptr ? firstLine->lineStartInFile : 0;
lines.set (firstAffectedLine, newFirstLine);
if (firstLine != nullptr)
{
const int index = pos.getIndexInLine();
textInsideOriginalLine = firstLine->line.substring (0, index)
+ textInsideOriginalLine
+ firstLine->line.substring (index);
}
if (newLines.size() > 1)
{
for (int i = 1; i < newLines.size(); ++i)
maximumLineLength = -1;
Array <CodeDocumentLine*> newLines;
CodeDocumentLine::createLines (newLines, textInsideOriginalLine);
jassert (newLines.size() > 0);
CodeDocumentLine* const newFirstLine = newLines.getUnchecked (0);
newFirstLine->lineStartInFile = firstLine != nullptr ? firstLine->lineStartInFile : 0;
lines.set (firstAffectedLine, newFirstLine);
if (newLines.size() > 1)
{
CodeDocumentLine* const l = newLines.getUnchecked (i);
lines.insert (firstAffectedLine + i, l);
lines.insertArray (firstAffectedLine + 1, newLines.getRawDataPointer() + 1, newLines.size() - 1);
lastAffectedLine = lines.size();
}
lastAffectedLine = lines.size();
}
int lineStart = newFirstLine->lineStartInFile;
for (int i = firstAffectedLine; i < lines.size(); ++i)
{
CodeDocumentLine& l = *lines.getUnchecked (i);
l.lineStartInFile = lineStart;
lineStart += l.lineLength;
}
int i, lineStart = newFirstLine->lineStartInFile;
for (i = firstAffectedLine; i < lines.size(); ++i)
{
CodeDocumentLine* const l = lines.getUnchecked (i);
l->lineStartInFile = lineStart;
lineStart += l->lineLength;
}
checkLastLineStatus();
checkLastLineStatus();
const int newTextLength = text.length();
for (int i = 0; i < positionsToMaintain.size(); ++i)
{
CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i);
const int newTextLength = text.length();
for (i = 0; i < positionsToMaintain.size(); ++i)
{
CodeDocument::Position* const p = positionsToMaintain.getUnchecked(i);
if (p.getPosition() >= insertPos)
p.setPosition (p.getPosition() + newTextLength);
}
if (p->getPosition() >= insertPos)
p->setPosition (p->getPosition() + newTextLength);
sendListenerChangeMessage (firstAffectedLine, lastAffectedLine);
}
sendListenerChangeMessage (firstAffectedLine, lastAffectedLine);
}
}
@@ -862,13 +843,11 @@ void CodeDocument::insert (const String& text, const int insertPos, const bool u
class CodeDocumentDeleteAction : public UndoableAction
{
public:
CodeDocumentDeleteAction (CodeDocument& owner_, const int startPos_, const int endPos_) noexcept
: owner (owner_),
startPos (startPos_),
endPos (endPos_)
CodeDocumentDeleteAction (CodeDocument& doc, const int start, const int end) noexcept
: owner (doc), startPos (start), endPos (end),
removedText (doc.getTextBetween (CodeDocument::Position (doc, start),
CodeDocument::Position (doc, end)))
{
removedText = owner.getTextBetween (CodeDocument::Position (&owner, startPos),
CodeDocument::Position (&owner, endPos));
}
bool perform()
@@ -885,12 +864,12 @@ public:
return true;
}
int getSizeInUnits() { return removedText.length() + 32; }
int getSizeInUnits() { return (endPos - startPos) + 32; }
private:
CodeDocument& owner;
int startPos, endPos;
String removedText;
const int startPos, endPos;
const String removedText;
JUCE_DECLARE_NON_COPYABLE (CodeDocumentDeleteAction);
};
@@ -906,57 +885,55 @@ void CodeDocument::remove (const int startPos, const int endPos, const bool undo
}
else
{
Position startPosition (this, startPos);
Position endPosition (this, endPos);
Position startPosition (*this, startPos);
Position endPosition (*this, endPos);
maximumLineLength = -1;
const int firstAffectedLine = startPosition.getLineNumber();
const int endLine = endPosition.getLineNumber();
int lastAffectedLine = firstAffectedLine + 1;
CodeDocumentLine* const firstLine = lines.getUnchecked (firstAffectedLine);
CodeDocumentLine& firstLine = *lines.getUnchecked (firstAffectedLine);
if (firstAffectedLine == endLine)
{
firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine())
+ firstLine->line.substring (endPosition.getIndexInLine());
firstLine->updateLength();
firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine())
+ firstLine.line.substring (endPosition.getIndexInLine());
firstLine.updateLength();
}
else
{
lastAffectedLine = lines.size();
CodeDocumentLine* const lastLine = lines.getUnchecked (endLine);
jassert (lastLine != nullptr);
CodeDocumentLine& lastLine = *lines.getUnchecked (endLine);
firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine())
+ lastLine->line.substring (endPosition.getIndexInLine());
firstLine->updateLength();
firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine())
+ lastLine.line.substring (endPosition.getIndexInLine());
firstLine.updateLength();
int numLinesToRemove = endLine - firstAffectedLine;
lines.removeRange (firstAffectedLine + 1, numLinesToRemove);
}
int i;
for (i = firstAffectedLine + 1; i < lines.size(); ++i)
for (int i = firstAffectedLine + 1; i < lines.size(); ++i)
{
CodeDocumentLine* const l = lines.getUnchecked (i);
const CodeDocumentLine* const previousLine = lines.getUnchecked (i - 1);
l->lineStartInFile = previousLine->lineStartInFile + previousLine->lineLength;
CodeDocumentLine& l = *lines.getUnchecked (i);
const CodeDocumentLine& previousLine = *lines.getUnchecked (i - 1);
l.lineStartInFile = previousLine.lineStartInFile + previousLine.lineLength;
}
checkLastLineStatus();
const int totalChars = getNumCharacters();
for (i = 0; i < positionsToMaintain.size(); ++i)
for (int i = 0; i < positionsToMaintain.size(); ++i)
{
CodeDocument::Position* p = positionsToMaintain.getUnchecked(i);
CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i);
if (p->getPosition() > startPosition.getPosition())
p->setPosition (jmax (startPos, p->getPosition() + startPos - endPos));
if (p.getPosition() > startPosition.getPosition())
p.setPosition (jmax (startPos, p.getPosition() + startPos - endPos));
if (p->getPosition() > totalChars)
p->setPosition (totalChars);
if (p.getPosition() > totalChars)
p.setPosition (totalChars);
}
sendListenerChangeMessage (firstAffectedLine, lastAffectedLine);


+ 15
- 16
modules/juce_gui_extra/code_editor/juce_CodeDocument.h View File

@@ -77,7 +77,7 @@ public:
Lines are numbered from zero, and if the line or index are beyond the bounds of the document,
they will be adjusted to keep them within its limits.
*/
Position (const CodeDocument* ownerDocument,
Position (const CodeDocument& ownerDocument,
int line, int indexInLine) noexcept;
/** Creates a position based on a character index in a document.
@@ -87,7 +87,7 @@ public:
If the position is beyond the range of the document, it'll be adjusted to keep it
inside.
*/
Position (const CodeDocument* ownerDocument,
Position (const CodeDocument& ownerDocument,
int charactersFromStartOfDocument) noexcept;
/** Creates a copy of another position.
@@ -101,6 +101,7 @@ public:
~Position();
Position& operator= (const Position& other);
bool operator== (const Position& other) const noexcept;
bool operator!= (const Position& other) const noexcept;
@@ -159,18 +160,18 @@ public:
characters.
@see moveBy
*/
const Position movedBy (int characterDelta) const;
Position movedBy (int characterDelta) const;
/** Returns a position which is the same as this one, moved up or down by the specified
number of lines.
@see movedBy
*/
const Position movedByLines (int deltaLines) const;
Position movedByLines (int deltaLines) const;
/** Returns the character in the document at this position.
@see getLineText
*/
const juce_wchar getCharacter() const;
juce_wchar getCharacter() const;
/** Returns the line from the document that this position is within.
@see getCharacter, getLineNumber
@@ -334,32 +335,30 @@ public:
class JUCE_API Iterator
{
public:
Iterator (CodeDocument* document);
Iterator (const Iterator& other);
Iterator (const CodeDocument& document) noexcept;
Iterator (const Iterator& other) noexcept;
Iterator& operator= (const Iterator& other) noexcept;
~Iterator() noexcept;
/** Reads the next character and returns it.
@see peekNextChar
*/
juce_wchar nextChar();
juce_wchar nextChar() noexcept;
/** Reads the next character without advancing the current position. */
juce_wchar peekNextChar() const;
juce_wchar peekNextChar() const noexcept;
/** Advances the position by one character. */
void skip();
void skip() noexcept;
/** Returns the position of the next character as its position within the
whole document.
*/
/** Returns the position as the number of characters from the start of the document. */
int getPosition() const noexcept { return position; }
/** Skips over any whitespace characters until the next character is non-whitespace. */
void skipWhitespace();
void skipWhitespace() noexcept;
/** Skips forward until the next character will be the first character on the next line */
void skipToEndOfLine();
void skipToEndOfLine() noexcept;
/** Returns the line number of the next character. */
int getLine() const noexcept { return line; }
@@ -368,7 +367,7 @@ public:
bool isEOF() const noexcept;
private:
CodeDocument* document;
const CodeDocument* document;
mutable String::CharPointerType charPointer;
int line, position;
};


+ 45
- 61
modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp View File

@@ -45,7 +45,7 @@ public:
}
else if (lineNum < document.getNumLines())
{
const CodeDocument::Position pos (&document, lineNum, 0);
const CodeDocument::Position pos (document, lineNum, 0);
createTokens (pos.getPosition(), pos.getLineText(),
source, *tokeniser, newTokens);
}
@@ -59,7 +59,7 @@ public:
{
const String line (document.getLine (lineNum));
CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0);
CodeDocument::Position lineStart (document, lineNum, 0), lineEnd (document, lineNum + 1, 0);
newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()),
line, spacesPerTab);
newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()),
@@ -71,24 +71,9 @@ public:
highlightColumnStart = newHighlightStart;
highlightColumnEnd = newHighlightEnd;
}
else
else if (tokens == newTokens)
{
if (tokens.size() == newTokens.size())
{
bool allTheSame = true;
for (int i = newTokens.size(); --i >= 0;)
{
if (tokens.getReference(i) != newTokens.getReference(i))
{
allTheSame = false;
break;
}
}
if (allTheSame)
return false;
}
return false;
}
tokens.swapWithArray (newTokens);
@@ -144,14 +129,14 @@ public:
private:
struct SyntaxToken
{
SyntaxToken (const String& text_, const int type) noexcept
: text (text_), tokenType (type), width (-1.0f)
SyntaxToken (const String& t, const int type) noexcept
: text (t), tokenType (type), width (-1.0f)
{
}
bool operator!= (const SyntaxToken& other) const noexcept
bool operator== (const SyntaxToken& other) const noexcept
{
return text != other.text || tokenType != other.tokenType;
return tokenType == other.tokenType && text == other.text;
}
String text;
@@ -321,13 +306,13 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& document_,
horizontalScrollBar (false),
codeTokeniser (codeTokeniser_)
{
caretPos = CodeDocument::Position (&document_, 0, 0);
caretPos = CodeDocument::Position (document_, 0, 0);
caretPos.setPositionMaintained (true);
selectionStart = CodeDocument::Position (&document_, 0, 0);
selectionStart = CodeDocument::Position (document_, 0, 0);
selectionStart.setPositionMaintained (true);
selectionEnd = CodeDocument::Position (&document_, 0, 0);
selectionEnd = CodeDocument::Position (document_, 0, 0);
selectionEnd.setPositionMaintained (true);
setOpaque (true);
@@ -509,8 +494,8 @@ void CodeEditorComponent::rebuildLineTokens()
jassert (numNeeded == lines.size());
CodeDocument::Iterator source (&document);
getIteratorForPosition (CodeDocument::Position (&document, firstLineOnScreen, 0).getPosition(), source);
CodeDocument::Iterator source (document);
getIteratorForPosition (CodeDocument::Position (document, firstLineOnScreen, 0).getPosition(), source);
for (int i = 0; i < numNeeded; ++i)
{
@@ -686,7 +671,7 @@ CodeDocument::Position CodeEditorComponent::getPositionAt (int x, int y)
const int column = roundToInt ((x - (getGutterSize() - xOffset * charWidth)) / charWidth);
const int index = columnToIndex (line, column);
return CodeDocument::Position (&document, line, index);
return CodeDocument::Position (document, line, index);
}
//==============================================================================
@@ -727,25 +712,25 @@ void CodeEditorComponent::insertTabAtCaret()
bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop()
{
if (! getHighlightedRegion().isEmpty())
return false;
for (;;)
if (getHighlightedRegion().isEmpty())
{
const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine());
for (;;)
{
const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine());
if (currentColumn <= 0 || (currentColumn % spacesPerTab) == 0)
break;
if (currentColumn <= 0 || (currentColumn % spacesPerTab) == 0)
break;
moveCaretLeft (false, true);
}
moveCaretLeft (false, true);
}
const String selected (getTextInRange (getHighlightedRegion()));
const String selected (getTextInRange (getHighlightedRegion()));
if (selected.isNotEmpty() && selected.trim().isEmpty())
{
cut();
return true;
if (selected.isNotEmpty() && selected.trim().isEmpty())
{
cut();
return true;
}
}
return false;
@@ -776,8 +761,8 @@ void CodeEditorComponent::indentSelectedLines (const int spacesToAdd)
if (nonWhitespaceStart > 0 || lineText.trimStart().isNotEmpty())
{
const CodeDocument::Position wsStart (&document, line, 0);
const CodeDocument::Position wsEnd (&document, line, nonWhitespaceStart);
const CodeDocument::Position wsStart (document, line, 0);
const CodeDocument::Position wsEnd (document, line, nonWhitespaceStart);
const int numLeadingSpaces = indexToColumn (line, wsEnd.getIndexInLine());
const int newNumLeadingSpaces = jmax (0, numLeadingSpaces + spacesToAdd);
@@ -803,7 +788,6 @@ void CodeEditorComponent::cut()
bool CodeEditorComponent::copyToClipboard()
{
newTransaction();
const String selection (document.getTextBetween (selectionStart, selectionEnd));
if (selection.isNotEmpty())
@@ -876,7 +860,7 @@ bool CodeEditorComponent::moveCaretDown (const bool selecting)
newTransaction();
if (caretPos.getLineNumber() == document.getNumLines() - 1)
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
else
moveLineDelta (1, selecting);
@@ -888,7 +872,7 @@ bool CodeEditorComponent::moveCaretUp (const bool selecting)
newTransaction();
if (caretPos.getLineNumber() == 0)
moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting);
moveCaretTo (CodeDocument::Position (document, 0, 0), selecting);
else
moveLineDelta (-1, selecting);
@@ -936,7 +920,7 @@ bool CodeEditorComponent::scrollDown()
bool CodeEditorComponent::moveCaretToTop (const bool selecting)
{
newTransaction();
moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting);
moveCaretTo (CodeDocument::Position (document, 0, 0), selecting);
return true;
}
@@ -949,21 +933,21 @@ bool CodeEditorComponent::moveCaretToStartOfLine (const bool selecting)
if (index >= caretPos.getIndexInLine() && caretPos.getIndexInLine() > 0)
index = 0;
moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), index), selecting);
moveCaretTo (CodeDocument::Position (document, caretPos.getLineNumber(), index), selecting);
return true;
}
bool CodeEditorComponent::moveCaretToEnd (const bool selecting)
{
newTransaction();
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
return true;
}
bool CodeEditorComponent::moveCaretToEndOfLine (const bool selecting)
{
newTransaction();
moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting);
moveCaretTo (CodeDocument::Position (document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting);
return true;
}
@@ -1031,8 +1015,8 @@ bool CodeEditorComponent::deleteForwards (const bool moveInWholeWordSteps)
bool CodeEditorComponent::selectAll()
{
newTransaction();
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false);
moveCaretTo (CodeDocument::Position (&document, 0, 0), true);
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false);
moveCaretTo (CodeDocument::Position (document, 0, 0), true);
return true;
}
@@ -1070,14 +1054,14 @@ Range<int> CodeEditorComponent::getHighlightedRegion() const
void CodeEditorComponent::setHighlightedRegion (const Range<int>& newRange)
{
moveCaretTo (CodeDocument::Position (&document, newRange.getStart()), false);
moveCaretTo (CodeDocument::Position (&document, newRange.getEnd()), true);
moveCaretTo (CodeDocument::Position (document, newRange.getStart()), false);
moveCaretTo (CodeDocument::Position (document, newRange.getEnd()), true);
}
String CodeEditorComponent::getTextInRange (const Range<int>& range) const
{
return document.getTextBetween (CodeDocument::Position (&document, range.getStart()),
CodeDocument::Position (&document, range.getEnd()));
return document.getTextBetween (CodeDocument::Position (document, range.getStart()),
CodeDocument::Position (document, range.getEnd()));
}
//==============================================================================
@@ -1379,7 +1363,7 @@ void CodeEditorComponent::updateCachedIterators (int maxLineNum)
const int linesBetweenCachedSources = jmax (10, document.getNumLines() / maxNumCachedPositions);
if (cachedIterators.size() == 0)
cachedIterators.add (new CodeDocument::Iterator (&document));
cachedIterators.add (new CodeDocument::Iterator (document));
if (codeTokeniser != nullptr)
{
@@ -1458,8 +1442,8 @@ CodeEditorComponent::State::State (const State& other) noexcept
void CodeEditorComponent::State::restoreState (CodeEditorComponent& editor) const
{
editor.moveCaretTo (CodeDocument::Position (&editor.getDocument(), lastSelectionEnd), false);
editor.moveCaretTo (CodeDocument::Position (&editor.getDocument(), lastCaretPos), true);
editor.moveCaretTo (CodeDocument::Position (editor.getDocument(), lastSelectionEnd), false);
editor.moveCaretTo (CodeDocument::Position (editor.getDocument(), lastCaretPos), true);
if (lastTopLine > 0 && lastTopLine < editor.getDocument().getNumLines())
editor.scrollToLine (lastTopLine);


Loading…
Cancel
Save