TextEditor and getTextIndexAt


#1

Hi.

I’m using TextEditor::getTextIndexAt(x, y) in order to find which word the cursor is currently over.
I am subtracting the border left from the x and border top from the y coordinates of the mouse event (missing from getTextIndexAt(x, y) I guess, as the indent is being subtracted).
The TextEditor is set to automatically show the vertical and horizontal scroll bars if needed, but does not show them because the text can easily fit into the TextEditor

int TextEditor::getTextIndexAt (const int x, const int y) { return indexAtPosition ((float) (x + viewport->getViewPositionX() - leftIndent), (float) (y + viewport->getViewPositionY() - topIndent)); }

My problem:
For some reason, viewport->getViewPositionY() is not 0, resulting in an incorrect index returned; its like the TextEditor thinks it has scroll bars (shows a partial viewed component), only it doesn’t - it shows it completely.
When I shrink it enough for the scrolls bars to actually appear, it works.

I know I don’t supply a lot of details, but that’s all I’ve got.

Any help will be appreciated.
Thanks.


#2

The getTextIndexAt() method is used inside all the editor’s mouse-drag functions, so if it didn’t work, then it’d also fail to select the correct text with the mouse, and I’m not aware of any problems with that. Perhaps you’re just feeding it the wrong coordinates?


#3

Well I think I’ve found something.

When I do the following it works OK (the line feed is crucial):

setText("myText\r\nisCool");
setSize(someOtherWidth, someOtherHeight);

But when I do the following it gets messed up:

insertTextAtCaret("myText\r\nisCool");
setSize(someOtherWidth, someOtherHeight);

I resolved it by adding text only after I determined the size (can’t use setText()).


#4

So if I want to reproduce the problem, what exactly should I do? Can you give me a blob of code I could paste into the juce demo?


#5

I have just successfully reproduced it in JuceDemo:

In FontsAndTextDemo.cpp, change resized() to the following:

    void resized()
    {
		int startingHeight = 20;
		textBox.setText(String::empty);
		textBox.setBounds(0, 0, getWidth(), 20);
		textBox.insertTextAtCaret("The Quick Brown Fox Jumps Over The Lazy Dog\n\nAa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 0123456789");
		textBox.setBounds(0, 0, getWidth(), getHeight() * 0.3f);
		textBox.getTextIndexAt(0,0);
    }

And in order to confirm it, add the following line to TextEditor::getTextIndexAt() in juce_TextEditor.cpp, just before the return statement:

Now open JuceDemo and go to Fonts and Text and resize the window. You will see getViewPositionY printed in your output window, most of the time its not zero (and while its not zero, you can’t select text properly).
I experimented with it some and it seems that for this specific case, for every startHeight lower than 86 getViewPositionY() will return values greater than zero when scrolling is definitely not needed (and not shown).

I hope this helps.
Tsury.


#6

Thanks, that turned out to be a very very subtle problem in the Viewport class - I’ll get a fix checked in later today!


#7

My pleasure (really) :slight_smile: