GUI TextInput with multiple lines

I found https://doc.babylonjs.com/how_to/gui#inputtext

The InputText is a control used to let users insert text in a single line

What I’d like to use is a multiline inputtext field. Like a html <textarea>

Does anyone know how to achive this?

I am actually not that familiar with typescrypt and the GUI library yet, otherwise I would try to write it myself by modifying inputtext.

Thank you for your time!

Hello as I told you in your PM, I’m fine if someone wants to add the feature (which is not trivial because of all the cursor management)

Hiya F!

No solution, but I have created a testing playground…

https://www.babylonjs-playground.com/#3EF49E#75

There we have a stackPanel (line 32) and it contains 4 “controls” as children. First 3 are inputText controls (slightly different from each other)… and the 4th is a ScrollViewer control… a type of multi-line text thing.

THIS scrollViewer is slightly different than normal. ScrollViewers can have TWO types of controls within them:

  • A single textBlock control
  • A single vertical StackPanel … which can contain MANY controls of MANY kinds.

Shown… is the 2nd version… a scrollViewer with a vertical stackPanel inside… which has 3 children… a textBlock, then a rectangleControl (a nice border-able container for nearly ANYTHING including more stackPanels)… and then another textBlock.

SO, by using a stackPanel in the ScrollViewer… we have super-powered the ScrollViewer… allowing us to live-update the scrollViewer… by adding and removing textBlocks/anyControls. We might have to markAsDirty after additions and deletions

The most important thing… we have a text “area” that is wordWrapping and vertical-scroll-bar ACTIVE… AND can be updated live.

Now, back to the 3 inputText controls… and in particular… look at line 39 of the FIRST inputText control. We have an “observer”… it can watch for keypresses, and can “notify” us/other-things… WHEN a key has been pressed. Hmm.

You know where this is going, now, right? We watch for keypresses… and possibly change the .text of ANY textBlock control… ANYWHERE (like one that is inside-of the scrollViewer)… EACH keypress.

A person MIGHT want to put that first inputText control… as the first child of the stackPanel that is INSIDE-OF the scrollViewer (and maybe just remark-out input1 and input2, which are simply included for us to look-at and learn-from).

I dunno IF input.onBeforeKeyAddObservable CAN be used to write text into a scrollViewer… but maybe. By using a combination of controls such as these… a person MIGHT be able to “fake” a wordwrapping, side-scroll-active multi-line textArea simulator.

I don’t know if I will continue working on the demo/testing today, because my town just got another 10 inches of snow from a spring storm, and I have snow-cleanup work to do… soon. Perhaps you and/or other helpers… would like to advance this possibility. It’s something to try… what the heck.

You might want to somewhat/somehow hide the single-line inputText control, or at least hide/delete its outputted text… as you feed each keypress from it… into the scrollViewer textBlock(s)… thx to the input.onBeforeKeyAddObservable.

Good luck! Attn: SNOW FOR SALE! CHEAP! FREE SHIPPING!

@Wingnut

I checked out your playground, but I prefer a WYSIWYG textarea input, instead of a workaround. But the scrollbar is needed, so I will take a look into the stackpanel.

@Wingnut @Deltakosh

So far I was able to reproduce wordwrap in the textinput field.
inputTextAsArea

Now I have to understand the cursor management.
I was thinking of focusing on line wrap first.
Because I see different implementation approaches, but so far I would try to go this way:

  1. Calculate height ranges of lines.
  2. Determine what coordinate was clicked
  3. Map coordinate to according line range
  4. Put cursor to position

On the other hand I wonder if it would make more sense to treat the input as one line for the cursor and put it accordingly by calculating heights and width ‘on-the-fly’? I never worked with cursors before, so best approaches are welcome :wink:

Well I like your “one line at a time” idea :slight_smile:

I run into a problem with:
context.measureText().width

The clipText of the Area starts after 312 px (scrollLeft)
The width of the area is 200px.

My problem is that, the first line is measured with 115 px, but obviously takes nearly all the 200 px of the box? This way the absolute cursor position is determined wrong, if I click into the line.

The code part looks like this:

if (this._clickedCoordinateX && this._clickedCoordinateY) {

            // measure line width
            var selectedLineText = this._lines[this._selectedLineIndex];
            var clickedLineWidth = context.measureText(selectedLineText).width;
            var rightPosition = this._scrollLeft + clickedLineWidth;
            var absoluteCursorPositionX = rightPosition - this._clickedCoordinateX;

I am aware that the text can be smaller than the width of the box, this way absoluteCursorPositionX could be negativ, if I click behind the text, but what happens here seems to me that context.measureText().width gives me the wrong number.

Any ideas or thoughts?

AH! I figured that I have to use:

this._lines[this._selectedLineIndex].width;

which gives me the correct width! Now the cursor is at the right position.

1 Like

@Wingnut @Deltakosh

That’s how it looks in the moment.

What do you think?

4 Likes

Man! This looks awesome!

Hey, I’m quite interested in this, can you let me know if this is getting implemented ?
Is anyone working on it ?

Thanks for the head up.

1 Like

@Oswald

I will still continue to work on that,because I need it :smiley: but since my semester started I am kind of busy. I will try to put the code I adapted in a git, if someone wants to continue with this as soon as I have time.

In the moment its missing

  • margin
  • text selection

and do not forget the unforeseen issues.

Further I was thinking to use verticalStackPanel to add a scrollbar. But first I wanted to implement the other things.

So far

1 Like

@Oswald @Deltakosh @Necips @Wingnut @sebavan

Sorry for the delay.

Here is the current state as described above.

I would be glad, about critical code reviews, so it may can be a PR if it’s done.

Best

2 Likes

To be acceptable as a PR the opposite is true. A PR must contain comments following these guidelines https://doc.babylonjs.com/how_to/contribute_to_api#format-of-comments

Comments are stripped during compilation for the babylon.min.js file.

2 Likes

This is super cool. Please make it part of Babylon JS!

1 Like

@fneitzel, totally agree, you should definitely create a PR with the current state and we can go from their :slight_smile:

@sebavan Seriously? I mean this is half baked code so far, which needs lots of improvements. But I will make a PR lets see what happens :smiley:

You can mark the PR as draft and we ll have a look with @Deltakosh to provide all the required feedbacks. There is no rush and in the end you would have contributed a nice new controls which has been requested by the community :slight_smile:

Thanks for your advice and support. Sounds like a good plan and otherwise I will come back to it anyway :smiley:

1 Like

Yup we ll see where it goes but it is an open issue so I guess it is an amazing idea : Multi-line support for InputBox · Issue #5630 · BabylonJS/Babylon.js · GitHub

1 Like

Hello !

My necrommancer skills allow me to revive this topic by adding my PR here : Improved prototype of InputTextArea by Valerian-Perez-Wanadev · Pull Request #11710 · BabylonJS/Babylon.js · GitHub

It’s not totaly perfet but now I’m lost how to finish the component. Maybe some of you have the spark of genius to complete it !

1 Like