How could I get all the lines of a TextBox if it has MultiLine enabled?

So if a textbox has multiline it automatically creates a new line because it went past the textbox size

For example
image

How could I turn that into

{
[1] = “Lorem ipsum dolor sit amet, consectetur adipiscing elit.”,
[2] = " Maecenas eget convallis velit. Vivamus porta pulvinar aliquet."
}

Or something like that

You could have a table to store the strings and a variable for the max characters per line. EX:

local maxchars = 60 — I’m going with 60 here, adjust according to situation
local mtable = {}
local message = — the chatted string here
local lines = string.len(message) / maxchars 
for i = 0, (lines-1) do
   table.insert(mtable, string.sub(message, (i * maxchars) + 1, maxchars * (i+1))
end

Basically, we’re getting the number of lines in the message typed. Then we’re adding the strech of string from the start of the line to the next to the table proportionate to the number of lines in the string. Please take note that I made this without testing as I can’t open studio yet, so expect bugs. Nevertheless, this is the framework for your query

But what if I don’t know the max characters

What if it’s a textbox somebody else made I wouldn’t know what the limits would be

Ah, then it gets complicated. What I did is manually count the number of characters the box can hold without jumping to the next line. I’m currently not aware of how to do this dynamically. I’ll experiment around and get back to you soon

Maybe you can split the string by spaces and then use TextService to get the text size and then check if it’s more than the AbsoluteSize of the textbox

I would code all this myself but it’s night time and I should probably go to bed soon

You can do that with TextService? That’s interesting, I’ll search it up

1 Like

Did you get something that works yet?

local lines, fontProperties = {}, {
			textbox.TextSize, 
			textbox.Font, 
			textbox.AbsoluteSize
		}
		
		local getTextSize = function(s)
			return TextService:GetTextSize(s, unpack(fontProperties))
		end
		
		local nth, size, currentText = 0, textbox.TextBounds, ""
		
		for i = 1, size.Y / textbox.TextSize do
			print(i, nth)
			nth += 1
			
			for i = 1, #textbox.Text:sub(nth) do
				local textSize = getTextSize(textbox.Text:sub(nth, nth + i))
				
				if textSize.Y > textbox.TextSize then
					local text = textbox.Text:sub(nth, nth + i - 1)
					table.insert(lines, {text, textSize})
					nth += i - 1
					
					break
				end
			end
		end
		
		table.insert(lines, {textbox.Text:sub(nth), getTextSize(textbox.Text:sub(nth))})
		

Ok this kind of works but when you add a space to a long piece of text that has not been wrapped yet and then add more after that it will result in this

image

and Idk how to detect that I tried but it didn’t work

Hey can somebody pls help me thanks

Hey it’s been a day lol u got anything yet ?

I know it’s a bit weird, but it works:

-- parses newlines created by the Enter/Return key into "\n"
local function parse_newlines(str: string): string
	return string.gsub(str, "\n", "\\n")
end

-- splits string by "\n"
local function split_newlines(str: string): {string}
	return string.split(parse_newlines(str), "\\n")
end

print(split_newlines("Hello, World!\nMy name is:\nMy. Robot"))
print(split_newlines([[Hello, World!
My name is:
Mr. Robot]]))
1 Like

No I mean like the lines of text that are created after typing too much

local lines, fontProperties = {}, {
			textbox.TextSize, 
			textbox.Font, 
			textbox.AbsoluteSize
		}
		
		local getTextSize = function(s)
			return TextService:GetTextSize(s, unpack(fontProperties))
		end
		
		local nth, size, currentText = 0, textbox.TextBounds, ""

		local lineCount = size.Y / textbox.TextSize
		
		local oneLine = (textbox.TextBounds.Y <= textbox.TextSize or lineCount == 1)
		
		for i = 1, lineCount do
			nth += 1
		
			for x = #textbox.Text - nth, 1, -1 do
				local text = textbox.Text:sub(nth, nth + x)
				local textSize = getTextSize(textbox.Text:sub(nth, nth + x))

				if textSize.Y <= textbox.TextSize then
					print(nth, x, textbox.Text:sub(nth, nth + x))
					text = text:gsub("%s+[^%s]*$", function(s)
						if not oneLine then
							print(s)
							lines[i + 1] = {s, getTextSize(s)}
							
							return "" --text:match(`(.*){s}`)
						end
					end)
					print(text)
					
					print(lines[i], i)
					
					if lines[i] then
						text = lines[i][1] .. text
						textSize = getTextSize(text)
						
						if textSize.Y > textbox.TextSize then
							for i = 1, #text do
								textSize = getTextSize(text:sub(1, i))

								if textSize.Y > textbox.TextSize then
									table.insert(lines, {text:sub(i), getTextSize(text:sub(i))})
									text = text:sub(1, i)

									break
								end
							end
						end
					--[[
						
						lines[i] = {text, textSize}
					else
						lines[i] = {text, textSize}
						]]
					end
					
					lines[i] = {text, textSize}
					
					nth += x
					
					break
				end
			end
		end
		
		if #lines ~= lineCount then
			warn("Number of lines do not match with the actual line count! (something must have gone wrong)")
		end

Ok I am almost done

Only bug is that if you put too much spaces in a line it will bug a lot

Help will be appreciated

local TextService = game:GetService("TextService")

return function(textbox : TextBox)
	local getPos = function(size, nth)
		local yAxis = Vector2.yAxis
		local End = Vector2.new(size.X, nth * textbox.TextSize) - yAxis * textbox.TextSize
		
		return {
			Start = End * yAxis,
			End = End
		}
	end
	
	local size = textbox.TextBounds
	local fullText = textbox.Text
	local lineCount = size.Y / textbox.TextSize
	
	local lines, fontProperties = {}, {
		textbox.TextSize, 
		textbox.Font, 
		textbox.AbsoluteSize
	}

	local getTextSize = function(s)
		return TextService:GetTextSize(s, unpack(fontProperties))
	end

	local nth, currentText = 1, ""

	for i = 1, lineCount do
		local text, textSize = fullText, size

		--nth += 1

		for y = 1, #fullText do
			text = fullText:sub(nth, nth + y)
			textSize = getTextSize(text)

			if textSize.Y > textbox.TextSize then
				text = text:sub(1, #text - 1)
				textSize = getTextSize(text)
				
				local matched = text:match(".*%s")

				if matched then
					text = matched

					textSize = getTextSize(text)
				end
				
				break
			end
		end

		if textSize.Y <= textbox.TextSize then
			table.insert(lines, {
				Text = text,
				Position = getPos(textSize, i)
			})

			nth += #text -- - 1
		end
	end

	if #lines ~= lineCount then
		warn("Number of lines do not match with the actual line count! (something must have gone wrong)")
	end

	return lines
end
local TextService = game:GetService("TextService")

local getPos = function(textbox : TextBox, X : number, line : number)
	local Y = line * textbox.TextSize -- size.Y
	
	local Alignments = {
		[Enum.TextXAlignment.Left] = X,
		[Enum.TextXAlignment.Right] = -X,
		[Enum.TextXAlignment.Center] = (textbox.AbsoluteSize.X / 2) + X / 2,
		[Enum.TextYAlignment.Top] = Y - textbox.TextSize,
		[Enum.TextYAlignment.Bottom] = textbox.AbsoluteSize.Y - Y, -- -Y
		[Enum.TextYAlignment.Center] = (textbox.AbsoluteSize.Y / 2) - Y / 2,
	}
	
	local End = Vector2.new(
		Alignments[textbox.TextXAlignment],	
		Alignments[textbox.TextYAlignment]
	)

	return {
		Start = End - (X * Vector2.xAxis),
		End = End
	}
end

return function(textbox : TextBox)
	local size = textbox.TextBounds
	local fullText = textbox.Text
	local lineCount = size.Y / textbox.TextSize

	local fontProperties, lines = 
	{
		textbox.TextSize, 
		textbox.Font, 
		textbox.AbsoluteSize
	}, 
	
	{
		{
			Text = textbox.Text,
			Position = getPos(textbox, size.X, 1)
		}
	}

	local getTextSize = function(s)
		return TextService:GetTextSize(s, unpack(fontProperties))
	end

	local nth, currentText = 1, ""

	for i = 1, lineCount do
		local text, textSize = fullText, size

		--nth += 1

		for y = 1, #fullText do
			text = fullText:sub(nth, nth + y)
			textSize = getTextSize(text)

			if textSize.Y > textbox.TextSize then
				text = text:sub(1, #text - 1)
				text = text:match(".*%s") or text

				textSize = getTextSize(text)

				break
			end
		end

		if textSize.Y <= textbox.TextSize then
			lines[i] = {
				Text = text,
				Position = getPos(textbox, textSize.X, i)
			}

			nth += #text -- - 1
		end
	end

	if #lines ~= lineCount then
		warn("Number of lines do not match with the actual line count! (something must have gone wrong)")
	end

	return lines
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.