Browse Source

Code editor fix for long lines.

tags/2021-05-28
jules 13 years ago
parent
commit
c2697bdce9
1 changed files with 44 additions and 23 deletions
  1. +44
    -23
      modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp

+ 44
- 23
modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp View File

@@ -41,7 +41,8 @@ public:
if (tokeniser == nullptr) if (tokeniser == nullptr)
{ {
newTokens.add (SyntaxToken (document.getLine (lineNum), -1));
const String line (document.getLine (lineNum));
addToken (newTokens, line, line.length(), -1);
} }
else if (lineNum < document.getNumLines()) else if (lineNum < document.getNumLines())
{ {
@@ -81,22 +82,29 @@ public:
} }
void draw (CodeEditorComponent& owner, Graphics& g, const Font& font, void draw (CodeEditorComponent& owner, Graphics& g, const Font& font,
float x, const float rightEdge, const int y, const int baselineOffset, const int lineHeight,
const float leftClip, const float rightClip,
const float xOffset, const int y, const int baselineOffset,
const int lineHeight, const float charWidth,
const Colour& highlightColour) const const Colour& highlightColour) const
{ {
if (highlightColumnStart < highlightColumnEnd) if (highlightColumnStart < highlightColumnEnd)
{ {
g.setColour (highlightColour); g.setColour (highlightColour);
g.fillRect (roundToInt (x + highlightColumnStart * owner.getCharWidth()), y,
g.fillRect (roundToInt (xOffset + highlightColumnStart * owner.getCharWidth()), y,
roundToInt ((highlightColumnEnd - highlightColumnStart) * owner.getCharWidth()), lineHeight); roundToInt ((highlightColumnEnd - highlightColumnStart) * owner.getCharWidth()), lineHeight);
} }
const float baselineY = (float) (y + baselineOffset); const float baselineY = (float) (y + baselineOffset);
Colour lastColour (0x00000001); Colour lastColour (0x00000001);
GlyphArrangement ga; GlyphArrangement ga;
int column = 0;
for (int i = 0; i < tokens.size(); ++i) for (int i = 0; i < tokens.size(); ++i)
{ {
const float tokenX = xOffset + column * charWidth;
if (tokenX > rightClip)
break;
SyntaxToken& token = tokens.getReference(i); SyntaxToken& token = tokens.getReference(i);
const Colour newColour (owner.getColourForTokenType (token.tokenType)); const Colour newColour (owner.getColourForTokenType (token.tokenType));
@@ -109,18 +117,11 @@ public:
g.setColour (newColour); g.setColour (newColour);
} }
ga.addCurtailedLineOfText (font, token.text, x, baselineY, rightEdge - x, false);
if (i < tokens.size() - 1)
{
if (token.width < 0)
token.width = font.getStringWidthFloat (token.text);
x += token.width;
column += token.length;
if (x > rightEdge)
break;
}
if (xOffset + column * charWidth >= leftClip)
ga.addCurtailedLineOfText (font, token.text, tokenX, baselineY,
(rightClip - tokenX) + charWidth, false);
} }
ga.draw (g); ga.draw (g);
@@ -129,19 +130,21 @@ public:
private: private:
struct SyntaxToken struct SyntaxToken
{ {
SyntaxToken (const String& t, const int type) noexcept
: text (t), tokenType (type), width (-1.0f)
SyntaxToken (const String& t, const int len, const int type) noexcept
: text (t), length (len), tokenType (type)
{ {
} }
bool operator== (const SyntaxToken& other) const noexcept bool operator== (const SyntaxToken& other) const noexcept
{ {
return tokenType == other.tokenType && text == other.text;
return tokenType == other.tokenType
&& length == other.length
&& text == other.text;
} }
String text; String text;
int length;
int tokenType; int tokenType;
float width;
}; };
Array <SyntaxToken> tokens; Array <SyntaxToken> tokens;
@@ -169,8 +172,9 @@ private:
if (tokenEnd > 0) if (tokenEnd > 0)
{ {
tokenStart -= startPosition; tokenStart -= startPosition;
newTokens.add (SyntaxToken (lineText.substring (jmax (0, tokenStart), tokenEnd),
tokenType));
const int start = jmax (0, tokenStart);
addToken (newTokens, lineText.substring (start, tokenEnd),
tokenEnd - start, tokenType);
if (tokenEnd >= lineLength) if (tokenEnd >= lineLength)
break; break;
@@ -219,6 +223,21 @@ private:
return col; return col;
} }
static void addToken (Array<SyntaxToken>& dest, const String& text,
const int length, const int type)
{
if (length > 1000)
{
// subdivide very long tokens to avoid unwieldy glyph sequences
addToken (dest, text.substring (0, length / 2), length / 2, type);
addToken (dest, text.substring (length / 2), length - length / 2, type);
}
else
{
dest.add (SyntaxToken (text, length, type));
}
}
}; };
namespace CodeEditorHelpers namespace CodeEditorHelpers
@@ -451,11 +470,13 @@ void CodeEditorComponent::paint (Graphics& g)
const int firstLineToDraw = jmax (0, clip.getY() / lineHeight); const int firstLineToDraw = jmax (0, clip.getY() / lineHeight);
const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1); const int lastLineToDraw = jmin (lines.size(), clip.getBottom() / lineHeight + 1);
const float x = (float) (gutter - xOffset * charWidth); const float x = (float) (gutter - xOffset * charWidth);
const float rightEdge = (float) getWidth();
const float leftClip = (float) clip.getX();
const float rightClip = (float) clip.getRight();
for (int i = firstLineToDraw; i < lastLineToDraw; ++i) for (int i = firstLineToDraw; i < lastLineToDraw; ++i)
lines.getUnchecked(i)->draw (*this, g, font, x, rightEdge, lineHeight * i,
baselineOffset, lineHeight, highlightColour);
lines.getUnchecked(i)->draw (*this, g, font, leftClip, rightClip,
x, lineHeight * i, baselineOffset,
lineHeight, charWidth, highlightColour);
} }
void CodeEditorComponent::setScrollbarThickness (const int thickness) void CodeEditorComponent::setScrollbarThickness (const int thickness)


Loading…
Cancel
Save