How to click and position the carat at the TextField correct character?

also how to drag and so select letters and words?
even on any label (button, etc…)

I actually mean if there is something already on that way implemented?

or I just have to implement the probable: guess the letter size (will work only with monospaced fonts), and calc based on the relative click position. If I could implement it in a pullable way to Lemur, I guess it would be a simple external/pluggable listener to any Label or TextField.

to initially guess the sure final font width, I create a new Label() with the current style, collect it’s BitmapText.getLineWidth() and divide by the number of chars on the text (monospaced only). I could just collect and label and do that too.

Yes, I am trying to provide editing capabilities, like word navigation (ctrl+left/right) etc

EDIT: also, it seems the mouse position is directly from lwjgl being the x,y on the app window. So I guess I would have to raycast and see where it hits in case of using a 3D rotated view of the user interface (I never used that to, I am just guessing we can attach it to other node than GuiNode).

EDIT: it is working (the carat positioning) but I stil feel I did a workaround (not proper implementation) despite I feel it will not break later as I used a new Label() using the TextField’s text and style, but I believe it could have been a more “to the point” code?

EDIT: to it work properly, I would need TextEntryComponent.textOffset to be exposed readonly thru get().

Random things:

  1. nothing exists as BitmapText is pretty icky and doesn’t easily support it. Getting the position in text based on a click is a matter of iteratively shortening the string until its length matches your x position and so on. Ugly.

  2. Cursor listener will tell you exactly where you clicked on the BitmapText… not sure why you’d need weird ray casting or whatever. Lemur is already doing that part for you.

  3. To set the carat position of the TextEntry you do it through its document model. Which… apparently doesn’t yet support setting the carat directly though you can fake it with home() and a bunch of right()s I guess. (ugh, sorry)

1 Like

it is working 99% now!

https://github.com/AquariusPower/DevConsLeJME/blob/master/Misc/src/main/java/com/github/devconslejme/misc/lemur/ClickToPositionCaratListenerI.java

I ended up doing a few, a bit too much indirect, things that one day may break I guess (steps 1,2 and 3):

  1. retrieve thru Node.getChildren a single BitmapText recursive child from the TextField, being actually TextField .text<TextEntryComponent> .bitmapText<BitmapText>. It’s world translation.x was necessary to:
  • determine the mouse cursor position relatively to it’s origin.
  • determine the carat Geometry, named “cursor”, position relatively to it’s origin (2).
  1. retrieve a single Geometry recursive child with debug name == “cursor” from the TextField

  2. determine the TextField’s mono spaced font letter width for it’s current style: by creating a new Label() and getting values from its BitmapText similarly to (1)

  3. calc the current “visible carat index” and the “new requested carat position from the mouse click”, using the letter width (3).

  4. make carat move relatively with .left() or .right()

To avoid 1, 2 and 3 breaking possibilities, some things would have to be exposed at least in readonly get() (unless I am missing where to properly collect them w/o using basically Node.getChildren()).

PS.: some of the pseudo-random stuff I said at the quite messy OP is part of the unavoidable creative brainstormed workaround process :sweat_smile: