How to make textboxes follow current cursor position?

I have a textbox that autoscales the text font to proper size. The textbox itself is within a beveled frame.
Problem is, when texting in the chatbox, the text doesnt auto scroll and follow the current cursor position
Gif
in the gif, the text just goes outside the bounds of the textbox. How do people make those textbox like they do for websites? you type, and any excess chars are followed by the cursor, and the older ones are tucked away?
Properties for the textbox:


Thanks for any advice, Alec

1 Like

I’m not fully understanding, so to make sure I have the right idea I’m going to ask for some clarification. Is this similar to what you are talking about?

https://gyazo.com/6b989587ed0af18145e6e016147a0dcd

1 Like

Yea exactly. Perfect example. I dont know the correct terminology, sorry

Not me either so don’t worry :grin:

I do have one idea, although a bit annoying.

Currently you have the TextXAlignment property of the TextBox set to Left.

My idea is detecting when the text reaches the end of the TextBox, and once it does reach the end, it will change the TextXAlignment property to Right. Meaning all the excess text will be pushed to the Left. But, you will still see it. You need to make sure the ClipDescendants property is true so that the text doesn’t keep going, it just cuts off.

To do what I said above, you will have to do a bit of scripting. If you can’t figure it out, I can give it a try as well.

Hint: You may need to use TextBounds for this :slight_smile:

2 Likes

I got bored, so I scripted it myself, and it was actually pretty simple.

local tb = script.Parent
tb.ClipDescendants = true
tb:GetPropertyChangedSignal("Text"):Connect(function()
	local bounds = tb.TextBounds
	local pixels = tb.AbsoluteSize.X
	if bounds >= pixels then
		tb.TextXAlignment = Enum.TextXAlignment.Right
	else
		tb.TextXAlignment = Enum.TextXAlignment.Left
	end
end)

https://gyazo.com/5e202a4e116008194573cdcf9bbcd8ad

7 Likes

One idea could also be to have one container object which just serves as a ClipsDescendants, and then have the TextLabel just slide around underneath that container.

This lets you do things like follow the cursor as you move it back and forth, closer to how web input boxes work.

I coded this example. Could add more features or whatever.

Setup:

image

Script:

local TextService = game:GetService("TextService")

local container = script.Parent -- should be a Frame or something like that
container.ClipsDescendants = true

local box = Instance.new("TextBox")
box.BorderSizePixel = 0
box.TextXAlignment = Enum.TextXAlignment.Left
box.ClearTextOnFocus = false
box.BackgroundTransparency = 1
box.Size = UDim2.new(5, 0, 1, 0)
box.Parent = container

local PADDING = 4 -- pixels to the left/right of text

local function Update()
	local reveal = container.AbsoluteSize.X
	
	if not box:IsFocused() or box.TextBounds.X <= reveal - 2 * PADDING then
		-- we aren't focused, or we fit so be normal
		box.Position = UDim2.new(0, PADDING, 0, 0)
	else
		-- we are focused and don't fit, so adjust position
		local cursor = box.CursorPosition
		if cursor ~= -1 then
			-- calculate pixel width of text from start to cursor
			local subtext = string.sub(box.Text, 1, cursor-1)
			local width = TextService:GetTextSize(subtext, box.TextSize, box.Font, Vector2.new(math.huge, math.huge)).X
			
			-- check if we're inside the box with the cursor
			local currentCursorPos = box.Position.X.Offset + width
			
			-- adjust if necessary
			if currentCursorPos < PADDING then
				box.Position = UDim2.fromOffset(PADDING-width, 0)
			elseif currentCursorPos > reveal - PADDING - 1 then
				box.Position = UDim2.fromOffset(reveal-width-PADDING-1, 0)
			end
		end
	end
end

Update()

-- might want to add more signals here (or just hook it to a render loop)
box:GetPropertyChangedSignal("Text"):Connect(Update)
box:GetPropertyChangedSignal("CursorPosition"):Connect(Update)
box.Focused:Connect(Update)
box.FocusLost:Connect(Update)

Results:

8 Likes

I would consider marking this as the solution as it handles following the cursor beyond the bounds of the text field container as well.

3 Likes

In case anyone else stumbles across this post like I did a couple months ago, Roblox has introduced scrolling for TextBoxes, removing the need to implement this behavior in code (and all the complications that come with it).