Need to change text in order for text editor to change text color


#1

I would like to change the color of the text in my text editor. I feel like this should do it:

mTextEditor->setColour(TextEditor::textColourId, juce::Colours::purple);

However, it appears that I need to change the text for the new color to take effect:

mTextEditor->setColour(TextEditor::textColourId, juce::Colours::purple);
mTrTextEditor->setText("???");

This won’t do it:

mTextEditor->setColour(TextEditor::textColourId, juce::Colours::purple);
mTextEditor->repaint();

And this won’t do it either:

mTextEditor->setColour(TextEditor::textColourId, juce::Colours::purple);
mTextEditor->setText(mTextEditor->getText());

So how do we change the color without changing the text?


#2

As I understand it, TextEditor supports different colours for different text fragments. If you look at TextEditor::setText(…):

Sets the entire content of the editor.
This will clear the editor and insert the given text (using the
current text colour and font). You can set the current text colour using
setColour (TextEditor::textColourId, …);

This is why setColour doen’t change anything, it only changes the colour for the next added text (also for void TextEditor::insertTextAtCaret (const String & textToInsert) ).

However, the code discards setting the same text:

So this should be changed IMHO, either simply remove the condition or check if the style attributes are also the same.

A workaround would be:

mTextEditor->selectAll();
mTextEditor->setColour (TextEditor::textColourId, juce::Colours::purple);
mTextEditor->insertTextAtCaret (mTextEditor->getText());

or simply call a different setText inbetween:

String text = mTextEditor->getText();
mTextEditor->clear();
mTextEditor->setColour (TextEditor::textColourId, juce::Colours::purple);
mTextEditor->setText (text);

until there is a better solution…
@juce: there is a void applyFontToAllText (const Font &newFont), maybe the same for the text colour would be adequate?


#3

WOW! Thank you so much for the thorough answer. I agree that something like applyColourToAllText() would be great. For now I used your clear() trick ;).


#4

Hi friends,

A call to mTextEditor->applyFontToAllText (Font()); right after setColour() worked for me. Let me know if it works in your code @vberthiaume

This is because I came across this comment in juce_TextEditor.h

/**< The colour that will be used when text is added to the editor. Note
     that because the editor can contain multiple colours, calling this
     method won't change the colour of existing text - to do that, call
     applyFontToAllText() after calling this method.*/

#5

Thanks for looking into. So textColourId is probably the first place to look for that side effect :wink:
Eventually you could copy that hint to setColour?

Also that only works for default fonts, what if the user already uses a different font in his text? Or even various fonts, as this is allowed also, see setFont…
Yes it is another workaround, but only for trivial cases…

And eventually that workflow of setting attributes to existing text is worth some rethinking. Iam sure you come up with a good solution, so that the methods are more telling what they do…


#6

Hi all,

Thank you so much for your help with this. @luigisambuy, that does work and just like you mention @daniel I did have to use my own font instead of the generic Font()


#7

Hi @luigisambuy,
sorry, couldn’t let go…
Would it be an option to change the behaviour of setColour and setFont like that:
If there is a selection, apply the change to the selection, otherwise keep the behaviour as it is to change the colour and font for future addings. I think that is consistent with what you can expect from using various text programs, and gives you full control…


#8

That sounds nice but would probably break a lot of existing code to just change the behaviour of methods.


#9

Yes, I was thinking about that… I don’t think that many people using the selection for programmatical changes, as at the moment you can’t alter the style of a selection.
But if you really need to preserve current behaviour, then probably this would be an idea:

void TextEditor::setFont (const Font &newFont, bool applyToSelection=false);
void TextEditor::setColour (int colourId, Colour newColour, bool applyToSelection=false);

It’s worth a thought…


#10

@daniel @vberthiaume
As per Daniel’s request, I changed the condition in setText() to let us change style using the same text. Now you should be able to call:

mTextEditor->setColour(TextEditor::textColourId, juce::Colours::purple);
mTextEditor->setText(mTextEditor->getText());

And this will write the text with the desired color. Note that any other change to colours other than TextEditor::textColourId will automatically update the TextEditor and therefore won’t need the SetText() call. You can find this change on the latest commit to the develop branch.


#11

thanks @luigisambuy, that simplifies some things…


#12

Sorry to bring up this old topic but I ran into some issues this morning with using multiple colours for different sections of text in a TextEditor and this seems to be the culprit. A call to setColour() using TextEditor::textColourId was applying the new colour to all the text in the TextEditor and overwriting any different colours.

I’ve reverted Luigi’s commit and added a TextEditor::applyColourToAllText() method which works in a similar way to TextEditor::applyFontToAllText() (see this commit) - so if you were relying on the previous behaviour then you may need to update your code to use this new method.