Text Wrapping

is there any derma object that uses text wrapping? I really don’t want to manually go through all my descriptions and manually add newlines.

I’ve tried HTML objects, DLabels, DTextEntries, nothing seems to have text wrapping.

Make your own.

I practically told you how in eye are see.

The formatting may look horrible, but I wanted to register it inside a script without creating any unnecessary locals. You could easily fix that part through, if needed.
[lua]
vgui.Register(“DTextWrapper”, {
[“Init”] = function(self)
self:SetSize(256, 18);
self:SetFont(“ChatFont”);
end,

["Paint"] = function(self)
	draw.RoundedBox(8, 0, 0, self:GetWide(), self:GetTall(), Color(70, 70, 70, self:GetAlpha())); // Draw our background.
	
	surface.SetFont(self:GetFont());
	local w, h = surface.GetTextSize("A"); // Get our lineheight.
	
	for line, text in pairs(self.Lines) do
		draw.SimpleText(text, self:GetFont(), 2, (h) * (line - 1), Color(255, 255, 255, self:GetAlpha())); // Draw the lines.
	end
end,

["SetText"] = function(self, text)
	surface.SetFont(self:GetFont());
	local w, h = surface.GetTextSize(text);
	
	local charw = surface.GetTextSize("A");
	local lastlinebreak = 1;
	
	for i = 1, string.len(text) do
		if(i == string.len(text)) then break; end // Don't add a linebreak to the end of the string.
		
		if(surface.GetTextSize(string.sub(text, lastlinebreak, i)) >= self:GetWide() - charw) then
			text = string.sub(text, 1, i) .. "

" … string.sub(text, i + 1, -1); // Add linebreaks.
lastlinebreak = i;
end
end

	self.Text = text; // Done.
	self.Lines = string.Explode("

", self:GetText()); // The same thing in a table.

	self:SetTall(h * #self.Lines); // Modify our height according to the number of lines.
end,

["GetText"] = function(self)
	return self.Text;
end,

["SetFont"] = function(self, font)
	self.Font = font;
end,

["GetFont"] = function(self)
	return self.Font;
end

});
[/lua]
I basically wrote this a while ago for my custom chatbox. I tried to scrap all the crap from it, so it could have an obvious error somewhere.

There are some things that you probably should fix if you’re planning to use this; if you change the width of the object while it has a text set, the current text will not re-wrap until you set a new text. Could probably be easily fixed by overwriting SetSize and SetWide, but I can’t be arsed to do that right now.

Please credit me in a small comment inside your script if you’re planning to use this, even if it’s just a small part of it.

I just made a quick amendment to the paint function for my thinger.

Here’s the code.

[lua]
local tbl = string.Explode( " ", self.Text )
local str = { “” }
local pos = 1

for k,v in pairs( tbl ) do
	
	local test = str[pos] .. " " .. v
	local size = surface.GetTextSize( test )
	
	if size > self:GetWide() - 40 then
	
		str[pos] = string.Trim( str[pos] )
		pos = pos + 1
		str[pos] = ( str[pos] or "" ) .. v
	
	else
	
		str[pos] = str[pos] .. " " .. v
	
	end
	
end

for k,v in pairs( str ) do

	draw.SimpleText( v, "ItemDisplayFont", 20, self:GetTall() * 0.85 + ( ( k - 1 ) * 15 ), Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT )

end[/lua]

I should probably be shot for doing this

[lua]
local function Wrap( string, width )
local tbl = {}
for key, value in pairs(markup.Parse(string, width).blocks) do
table.insert(tbl, value.text)
end
return tbl
end
[/lua]

width is in pixels

doesn’t do newlines though

You’re close CapsAdmin, but you can just keep the object returned by markup.Parse and call Draw on it ( the args you need are on the wiki ), which allows colors, mixed fonts, and other formatting.

You mean Draw, right?

Yeah, my bad. I always forget that.

Did you try DLabel:SetWrap(true)

This guy just won.

Used in part of Zinger
[lua]
// create description area
self.Description = vgui.Create( “DLabel”, self );
self.Description:SetText( “” );
self.Description:SetAutoStretchVertical( true );
self.Description:SetWide( 250 );
self.Description:SetWrap( true );
[/lua]

I never knew that such function existed until now.

Oh. Fuck me i guess. Should i keep the current code as it is or swap to a DLabel? Decisions…

When did that get there…

Quoted for truth. When did that get there? I don’t remember the wiki ever documenting it…

I was using this code
[lua]
function string.wrapwords(Str,font,width)
if( font ) then --Dr Magnusson’s much less prone to failure and more optimized version
surface.SetFont( font )
end

 local tbl, len, Start, End = {}, string.len( Str ), 1, 1  
   
 while ( End < len ) do  
     End = End + 1  
     if ( surface.GetTextSize( string.sub( Str, Start, End ) ) > width ) then  
         local n = string.sub( Str, End, End )  
         local I = 0  
         for i = 1, 15 do  
             I = i  
             if( n != " " and n != "," and n != "." and n != "

" ) then
End = End - 1
n = string.sub( Str, End, End )
else
break
end
end
if( I == 15 ) then
End = End + 14
end

         local FnlStr = string.Trim( string.sub( Str, Start, End ) )  
         table.insert( tbl, FnlStr )  
         Start = End + 1  
     end                   
 end  
 table.insert( tbl, string.sub( Str, Start, End ) )  
 return table.concat(tbl,"

")
end
[/lua]

The wiki page wasn’t made until today, therefore this function never existed until today. :colbert:

[editline]03:20PM[/editline]

Lua Scripting thread of the month.

http://luabin.foszor.com/code?search=setwrap

Its even used in Fretta.

I never trust the wiki when it comes to derma, the source is so much more… revealing

It’s not in the lua source either. It’s been derived from “Label” a C++ VGUI element.