Custom chatboxes?

I looked at a few custom chatboxes on garrysmod.org.
The only one with enough features to use as a base is… ugly. The code is a mess. All the chat elements are created every frame… I don’t believe this is the only way to do it.
Are there any good chat boxes that I could look at?

Even if it is messy it should you a basic idea of what hooks to use and how to handle the basic logic of it, if you are actually serious about learning and put some time into it then it will be a lot more rewarding than if you edit a few lines of someone elses script

A commented code could help too. But there isn’t any…
Anyway, I’ve found how do they do it. Overwriting the binding.

[lua]hook.Add(“PlayerBindPress”, “ChatBindPress”, OpenChatWindow) – Return true to signal that the binding has been handled.[/lua]

And you hide it when a message is sent.

Lol…

there is hooks for this don’t overwrite the bind

here is code from the chatbox i made.
[lua]
Chatbox = { }
Chatbox.Lines = { }

Chatbox.Show = false
Chatbox.ShowText = true
Chatbox.DefaultLines = 5
Chatbox.BasePos = ScrH() - 30
Chatbox.Offset = 18
Chatbox.MaxLines = 19
Chatbox.DefaultLineNum = Chatbox.DefaultLines*Chatbox.Offset

function Chatbox.Paint()
if ( Chatbox.Show ) then

	draw.RoundedBox( 6, 20, ScrH() - 320, 600, 300, Color( 0, 0, 0, 150 ) )
	
	for k,v in pairs( Chatbox.Lines ) do
		local pos = v[1]
		draw.DrawText( v[2], "ScoreboardText", 20, Chatbox.BasePos - pos, Color(255, 255, 255, 255),TEXT_ALIGN_LEFT)
	end
end

if ( Chatbox.ShowText == true ) then
	for k,v in pairs( Chatbox.Lines ) do
		if ( v[1] < Chatbox.DefaultLineNum ) then
			draw.DrawText( v[2] , "ScoreboardText", 20, Chatbox.BasePos - v[1], Color(255, 255, 255, 255),TEXT_ALIGN_LEFT)
		end
	end
end

end

hook.Add( “HUDPaint”, “ChatBoxPaint”, Chatbox.Paint)

function Chatbox:ShiftLines()
for k,v in pairs( self.Lines ) do
if ( !v[1] ) then return end

	self.Lines[ k ][ 1 ] = v[1] + Chatbox.Offset
	if ( v[1] > 285 ) then
		self.Lines[ k ] = nil
	end
end

end

function Chatbox:AddLine( text )
if ( !text ) then return end

self:ShiftLines();

table.insert( self.Lines, { 15, text } );

if ( self.Lines[ self.MaxLines ] ) then
	self.Lines[ 1 ] = nil
end

end

function GM:StartChat(teamsay)
Chatbox.Show = true
if ( !Chatbox.Entry ) then
Chatbox.Entry = vgui.Create(“DTextEntry”)
Chatbox.Entry:SetPos( 20, Chatbox.BasePos + 5 )
Chatbox.Entry:SetSize( 600, 20 )
Chatbox.Entry:SetVisible( true );
end
Chatbox.Entry:SetVisible( true );
return true
end

function GM:FinishChat( )
Chatbox.Show = false
if ( Chatbox.Entry ) then
Chatbox.Entry:SetVisible( false );
end
return true
end

function GM:ChatTextChanged(text)
if ( Chatbox.Entry and Chatbox.Entry:IsVisible() ) then
Chatbox.Entry:SetText( text );
end
end

function OnChatRecieved( data )
local text = data:ReadString();
Chatbox:AddLine( text );
–Chatbox.Entry:SetText("");
end
usermessage.Hook(“OnChatRecieved”, OnChatRecieved )
[/lua]

[lua]
function Talk( player, radius, text)

for k, v in pairs( ents.FindInSphere( player:GetPos( ), tonumber(radius)) ) do

	if ( v:IsPlayer() ) then
		umsg.Start("OnChatRecieved", v )
			umsg.String( text )
		umsg.End()
	end

end

end

COMMANDS = { }

function COMMANDS:New( cmd, func )
if ( !cmd or !func ) then return end

self[ cmd ] = func

end

COMMANDS:New( “/y”, function( player, raw )
Talk( player, 900, player:Nick() … " yells ‘" … raw … "’")
end)

COMMANDS:New( “/w”, function( player, raw )
Talk( player, 100, player:Nick() … " whispers ‘" … raw … "’")
end)

COMMANDS:New( “/me”, function( player, raw )
Talk( player, 900, player:Nick() … raw )
end)

COMMANDS:New( “//”, function( playerr, raw )
for k,v in pairs( player.GetAll() ) do
umsg.Start(“OnChatRecieved”, v )
umsg.String( “[OOC]” … playerr:Nick() … ": " … raw )
umsg.End()
end
end)

COMMANDS:New( “.//”, function( player, raw )
Talk( player, 1000, “[LOOC]” … player:Nick() … " : " … raw )
end)

COMMANDS:New( “/description”, function( player, raw )
if ( string.len(raw) > 10 ) then
player:SetPData(“Description”, raw );
end
end)

function GM:PlayerSay( player, text, public)

for k,v in pairs ( COMMANDS ) do

local cmd_len = string.len(tostring(k))

if ( string.sub(k, 1, cmd_len) == string.sub(text, 1, cmd_len) ) then
	local raw = string.sub(text, cmd_len + 1)
	v( player, raw );
	return ""
end

end
Talk( player, 300, player:Nick() … " says ‘" … text … "’" )
return “”
end
[/lua]

Ah, so these are the hooks that do the job.
Just one thing.
Your “typed” message is on an invisible text box.
When you type in it, the text on another text box updates.
But what about the caret? How do you edit text?
Nvm, I’ll handle that myself somehow.

Thank you so much! :smiley:

where to put in xD ??

if you’d like, you can take a look at my chatbox, although it’s a little cluttered it overrides chat.AddText instead of just making the default chatbox invisible and copying the text