Text input widget; batch text.
This commit is contained in:
parent
4d084488f7
commit
e7926fab3c
Binary file not shown.
|
@ -0,0 +1,15 @@
|
||||||
|
return {
|
||||||
|
name = "Player Name",
|
||||||
|
pronoun = "they",
|
||||||
|
colour = {0.8, 0.4, 0.4, 0.7},
|
||||||
|
gamma = 0.5,
|
||||||
|
keybinds = {
|
||||||
|
forward = "w",
|
||||||
|
back = "s",
|
||||||
|
left = "a",
|
||||||
|
right = "d",
|
||||||
|
chat = "t",
|
||||||
|
love = "q",
|
||||||
|
hate = "e",
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,14 +7,16 @@ local udp = socket.udp()
|
||||||
local game = {}
|
local game = {}
|
||||||
local t = 0
|
local t = 0
|
||||||
local tick = 0
|
local tick = 0
|
||||||
|
local serverTick = "0"
|
||||||
|
|
||||||
|
|
||||||
function game.draw()
|
function game.draw()
|
||||||
|
lg.print( tick, 0, 0 )
|
||||||
|
lg.print( serverTick, 0, 25 )
|
||||||
end
|
end
|
||||||
|
|
||||||
function game.onPacket( data, msg )
|
function game.onPacket( data, msg )
|
||||||
if data then print( data, msg ) end
|
if data then serverTick = data end
|
||||||
end
|
end
|
||||||
|
|
||||||
function game.update( dt )
|
function game.update( dt )
|
||||||
|
@ -36,9 +38,11 @@ function game.disconnect( )
|
||||||
return scene.mainmenu()
|
return scene.mainmenu()
|
||||||
end
|
end
|
||||||
|
|
||||||
function game.onLoad( )
|
function game.onLoad( params )
|
||||||
|
params = params or {}
|
||||||
|
local serverIP, serverPort = params.serverIP or "192.168.2.15", params.serverPort or 51312
|
||||||
udp:settimeout( 0 )
|
udp:settimeout( 0 )
|
||||||
udp:setpeername( "192.168.2.15", 51312 )
|
udp:setpeername( serverIP, serverPort )
|
||||||
end
|
end
|
||||||
|
|
||||||
function game.keypressed( key, code, isRepeat )
|
function game.keypressed( key, code, isRepeat )
|
||||||
|
|
|
@ -2,12 +2,12 @@ local scene = {}
|
||||||
local love = assert( love )
|
local love = assert( love )
|
||||||
local mt = {}
|
local mt = {}
|
||||||
|
|
||||||
local function loadScene( scene )
|
local function loadScene( scene, params )
|
||||||
print( "Loading Scene:", scene.name )
|
print( "Loading Scene:", scene.name )
|
||||||
for k, v in pairs( scene ) do
|
for k, v in pairs( scene ) do
|
||||||
love[k] = v
|
love[k] = v
|
||||||
end
|
end
|
||||||
scene.onLoad()
|
scene.onLoad( params )
|
||||||
end
|
end
|
||||||
|
|
||||||
local function newScene( scenes, name, t )
|
local function newScene( scenes, name, t )
|
||||||
|
|
|
@ -1,9 +1,20 @@
|
||||||
local lg = assert( love.graphics )
|
local lg = assert( love.graphics )
|
||||||
local scene = assert( require 'client.scene' )
|
local scene = assert( require 'client.scene' )
|
||||||
|
local textInput = assert( require 'client.ui.textinput' )
|
||||||
|
local button = assert( require 'client.ui.button' )
|
||||||
local browser = {}
|
local browser = {}
|
||||||
|
|
||||||
|
local ti = textInput.new{
|
||||||
|
width = 300,
|
||||||
|
length = 20,
|
||||||
|
x = 15,
|
||||||
|
y = 165
|
||||||
|
}
|
||||||
|
|
||||||
function browser.draw()
|
function browser.draw()
|
||||||
lg.rectangle( "fill", 50, 50, 50, 50 )
|
lg.setColor( 1, 1, 1, 1 )
|
||||||
|
lg.print( "Server Browser", 15, 115 )
|
||||||
|
ti:draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
function browser.update( dt )
|
function browser.update( dt )
|
||||||
|
@ -14,12 +25,26 @@ function browser.onLoad( )
|
||||||
lg.setColor( 1, 1, 1, 1 )
|
lg.setColor( 1, 1, 1, 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
function browser.mousepressed()
|
function browser.mousepressed(x, y, button, istouch, pressed)
|
||||||
|
if ti:contains( x, y ) then return ti:enterText( browser.joinIPString ) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function browser.joinIPString( s )
|
||||||
|
--Parse IP address and port from string. If it's valid, join the server.
|
||||||
|
if not s then return end
|
||||||
|
ti:clear()
|
||||||
|
local valid, ip, port
|
||||||
|
|
||||||
|
if valid then return browser.joinIP( ip, port ) end
|
||||||
|
end
|
||||||
|
|
||||||
|
function browser.joinIP( ip, port )
|
||||||
|
return scene.game{ serverIP = ip, serverPort = port }
|
||||||
end
|
end
|
||||||
|
|
||||||
function browser.keypressed( key, code, isRepeat )
|
function browser.keypressed( key, code, isRepeat )
|
||||||
if code == "escape" then return scene.mainmenu() end
|
if code == "escape" then return scene.mainmenu() end
|
||||||
|
if code == "return" then return ti:enterText( browser.joinIPString ) end
|
||||||
end
|
end
|
||||||
|
|
||||||
scene.browser = browser
|
scene.browser = browser
|
||||||
|
|
|
@ -93,7 +93,7 @@ function menu.paint()
|
||||||
end
|
end
|
||||||
|
|
||||||
function menu.onLoad()
|
function menu.onLoad()
|
||||||
lg.setNewFont( "client/assets/SitkaB.ttc", 28 )
|
lg.setNewFont( 28 )
|
||||||
return menu.resize( lg.getDimensions() )
|
return menu.resize( lg.getDimensions() )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ local love = assert( love )
|
||||||
local scene = assert( require 'client.scene' )
|
local scene = assert( require 'client.scene' )
|
||||||
local strings = assert( require 'client.assets.strings' )
|
local strings = assert( require 'client.assets.strings' )
|
||||||
local button = assert( require 'client.ui.button' )
|
local button = assert( require 'client.ui.button' )
|
||||||
|
local textinput = assert( require 'client.ui.textinput' )
|
||||||
local menu = {}
|
local menu = {}
|
||||||
|
|
||||||
local t = 0
|
local t = 0
|
||||||
|
@ -21,40 +22,46 @@ local gradientQuad = lg.newMesh{
|
||||||
|
|
||||||
local buttons =
|
local buttons =
|
||||||
{
|
{
|
||||||
|
|
||||||
button{
|
button{
|
||||||
x = 15, w = 400, h = 50,
|
x = 15, w = 400, h = 50,
|
||||||
y = 115,
|
y = 115,
|
||||||
text = strings.option_name,
|
text = strings.mainmenu_button,
|
||||||
color = { 0.5, 0.2, 0.2, 0.6 },
|
color = { 0.5, 0.2, 0.8, 0.6 },
|
||||||
callback = function() print("Adjust Name") end },
|
callback = function() return scene.mainmenu() end },
|
||||||
|
|
||||||
button{
|
button{
|
||||||
x = 15, w = 400, h = 50,
|
x = 15, w = 400, h = 50,
|
||||||
y = 115 + 55,
|
y = 115 + 55,
|
||||||
text = strings.option_pron,
|
option = 'name',
|
||||||
color = { 0.5, 0.2, 0.4, 0.6 },
|
text = strings.option_name,
|
||||||
callback = function() print("Adjust Name") end },
|
color = { 0.5, 0.2, 0.2, 0.6 },
|
||||||
|
callback = menu.textOption },
|
||||||
|
|
||||||
button{
|
button{
|
||||||
x = 15, w = 400, h = 50,
|
x = 15, w = 400, h = 50,
|
||||||
y = 115 + 55 * 2,
|
y = 115 + 55 * 2,
|
||||||
text = strings.option_tint,
|
option = 'pronoun',
|
||||||
color = { 0.5, 0.2, 0.6, 0.6 },
|
text = strings.option_pron,
|
||||||
callback = function() print("Adjust Colour") end },
|
color = { 0.5, 0.2, 0.4, 0.6 },
|
||||||
|
callback = menu.textOption },
|
||||||
|
|
||||||
button{
|
button{
|
||||||
x = 15, w = 400, h = 50,
|
x = 15, w = 400, h = 50,
|
||||||
y = 115 + 55 * 3,
|
y = 115 + 55 * 3,
|
||||||
text = strings.mainmenu_button,
|
option = 'colour',
|
||||||
color = { 0.5, 0.2, 0.8, 0.6 },
|
text = strings.option_tint,
|
||||||
callback = function() print("Adjust Name") return scene.mainmenu() end },
|
color = { 0.5, 0.2, 0.6, 0.6 },
|
||||||
|
callback = menu.colourOption },
|
||||||
|
|
||||||
|
|
||||||
button{
|
button{
|
||||||
x = 15, w = 400, h = 50,
|
x = 15, w = 400, h = 50,
|
||||||
y = 115 + 55 * 4,
|
y = 115 + 55 * 4,
|
||||||
|
option = 'keybinds',
|
||||||
text = strings.keybinding_button,
|
text = strings.keybinding_button,
|
||||||
color = { 0.8, 0.0, 0.4, 0.8 },
|
color = { 0.8, 0.0, 0.4, 0.8 },
|
||||||
callback = function() end,
|
callback = menu.editKeybinds,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +85,7 @@ local buttons =
|
||||||
}]]
|
}]]
|
||||||
|
|
||||||
function menu.onLoad()
|
function menu.onLoad()
|
||||||
lg.setNewFont( "client/assets/SitkaB.ttc", 28 )
|
lg.setNewFont( 28 )
|
||||||
return menu.resize( lg.getDimensions() )
|
return menu.resize( lg.getDimensions() )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,7 +144,7 @@ end
|
||||||
function menu.mousepressed( x, y, button, istouch, presses )
|
function menu.mousepressed( x, y, button, istouch, presses )
|
||||||
if not selectedButtonIdx then return end
|
if not selectedButtonIdx then return end
|
||||||
local uiButton = buttons[selectedButtonIdx]
|
local uiButton = buttons[selectedButtonIdx]
|
||||||
if uiButton:contains( x, y ) then return uiButton() end
|
if uiButton:contains( x, y ) then return uiButton( ) end
|
||||||
|
|
||||||
return menu.paint()
|
return menu.paint()
|
||||||
end
|
end
|
||||||
|
@ -149,7 +156,7 @@ function menu.keypressed( key, code, isrepeat )
|
||||||
end
|
end
|
||||||
|
|
||||||
if code == "return" and selectedButtonIdx then
|
if code == "return" and selectedButtonIdx then
|
||||||
return buttons[selectedButtonIdx]()
|
return buttons[selectedButtonIdx].callback()
|
||||||
end
|
end
|
||||||
|
|
||||||
if code == "down" or code == "tab" or code == "up" then
|
if code == "down" or code == "tab" or code == "up" then
|
||||||
|
|
|
@ -5,65 +5,107 @@ local lg = assert( love.graphics )
|
||||||
local utf8 = assert( require 'utf8' )
|
local utf8 = assert( require 'utf8' )
|
||||||
local string = assert( string )
|
local string = assert( string )
|
||||||
|
|
||||||
|
|
||||||
local _lt
|
local _lt
|
||||||
local _lkp
|
local _lkp
|
||||||
|
local _lmm
|
||||||
|
local _lmp
|
||||||
|
local _callback
|
||||||
|
|
||||||
|
|
||||||
local textInput = { }
|
local textInput = { }
|
||||||
local __mt = { __index = textInput }
|
local __mt = { __index = textInput }
|
||||||
|
|
||||||
|
local font = lg.newFont( 36 )
|
||||||
|
|
||||||
|
-- There is only one active text input widget at a time.
|
||||||
|
-- It takes exclusive control of key input.
|
||||||
local activeWidget
|
local activeWidget
|
||||||
|
|
||||||
function textInput.new()
|
textInput.width = 200
|
||||||
return setmetatable( {text = ""}, __mt )
|
textInput.length = 20
|
||||||
|
textInput.x = 0
|
||||||
|
textInput.y = 0
|
||||||
|
|
||||||
|
function textInput.new( t )
|
||||||
|
t = t or {}
|
||||||
|
t.text = lg.newText( font, "")
|
||||||
|
t.str = ""
|
||||||
|
return setmetatable( t, __mt )
|
||||||
end
|
end
|
||||||
|
|
||||||
--This is only called when a text input widget is active.
|
|
||||||
function textInput.keypressed(key, code, isRepeat)
|
function textInput.keypressed(key, code, isRepeat)
|
||||||
assert( activeWidget )
|
if activeWidget and textInput[code] then return textInput[code]() end
|
||||||
if code == "escape" then return textInput.escape() end
|
|
||||||
if code == "return" then return textInput.return() end
|
|
||||||
|
|
||||||
local text = activeWidget.text
|
|
||||||
if code == "backspace" then
|
|
||||||
local byteoffset = utf8.offset(text, -1)
|
|
||||||
|
|
||||||
if byteoffset then
|
|
||||||
-- remove the last UTF-8 character.
|
|
||||||
-- string.sub operates on bytes rather than UTF-8 characters, so we couldn't do string.sub(text, 1, -2).
|
|
||||||
text = string.sub(text, 1, byteoffset - 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function textInput:draw()
|
|
||||||
lg.rectangle( )
|
|
||||||
lg.print(self.text, self.x or 0, self.y or 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
function textInput:getText()
|
|
||||||
return self.text
|
|
||||||
end
|
|
||||||
|
|
||||||
function textInput.textInput( s )
|
|
||||||
activeWidget.text = activeWidget.text..s
|
|
||||||
end
|
|
||||||
|
|
||||||
function textInput:enable()
|
|
||||||
_lt = love.textinput
|
|
||||||
_lkp = love.keypressed
|
|
||||||
love.textinput = textInput.textInput
|
|
||||||
love.keypressed = textInput.keypressed
|
|
||||||
activeWidget = self
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function textInput:clear()
|
function textInput:clear()
|
||||||
|
self.str = ""
|
||||||
|
self.text:set( self.str )
|
||||||
end
|
end
|
||||||
|
|
||||||
function textInput.disable()
|
function textInput:contains(x, y)
|
||||||
|
local mx, my, Mx, My = self.x, self.y, self.x + self.width, self.y + font:getHeight()
|
||||||
|
return (x < Mx and x > mx and y > my and y < My)
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput:draw()
|
||||||
|
local w, h = self.text:getDimensions()
|
||||||
|
lg.setColor( 1, 1, 1, 0.5 )
|
||||||
|
lg.rectangle( "fill", self.x, self.y, w, h )
|
||||||
|
if activeWidget == self then lg.rectangle( "fill", self.x, self.y, self.width, font:getHeight(), 5 ) end
|
||||||
|
lg.rectangle( "line", self.x - 3, self.y - 3, self.width + 6, font:getHeight() + 6, 5 )
|
||||||
|
lg.setColor( 0, 0, 0, 1 )
|
||||||
|
lg.draw( self.text, self.x or 0, self.y or 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput:getText()
|
||||||
|
return self.str
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput.textInput( s )
|
||||||
|
activeWidget.str = activeWidget.str..s
|
||||||
|
activeWidget.text:set( activeWidget.str )
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput.backspace( )
|
||||||
|
local str = activeWidget.str
|
||||||
|
local byteoffset = utf8.offset(str, -1)
|
||||||
|
if byteoffset then str = string.sub(str, 1, byteoffset - 1)
|
||||||
|
else return end
|
||||||
|
activeWidget.str = str
|
||||||
|
activeWidget.text:set( activeWidget.str )
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput:enterText( callback )
|
||||||
|
_lt = love.textinput
|
||||||
|
_lkp = love.keypressed
|
||||||
|
_lmm = love.mousemoved
|
||||||
|
_lmp = love.mousepressed
|
||||||
|
_callback = assert( callback )
|
||||||
|
love.textinput = textInput.textInput
|
||||||
|
love.keypressed = textInput.keypressed
|
||||||
|
self.oldStr = self.str
|
||||||
|
activeWidget = self
|
||||||
|
end
|
||||||
|
|
||||||
|
local function disable()
|
||||||
|
activeWidget = nil
|
||||||
love.textinput = _lt
|
love.textinput = _lt
|
||||||
love.
|
love.keypressed = _lkp
|
||||||
|
love.mousemoved = _lmm
|
||||||
|
love.mousepressed = _lmp
|
||||||
|
end
|
||||||
|
|
||||||
|
function textInput.escape()
|
||||||
|
activeWidget.str = activeWidget.oldStr or ""
|
||||||
|
activeWidget.text:set( activeWidget.str )
|
||||||
|
disable()
|
||||||
|
return _callback()
|
||||||
|
end
|
||||||
|
|
||||||
|
textInput["return"] = function() --unusual decl because return is a keyword
|
||||||
|
local str = activeWidget.str
|
||||||
|
disable()
|
||||||
|
return _callback( str )
|
||||||
end
|
end
|
||||||
|
|
||||||
return textInput
|
return textInput
|
|
@ -9,9 +9,7 @@ local server = {
|
||||||
serverName = "dajjal-server",
|
serverName = "dajjal-server",
|
||||||
}
|
}
|
||||||
|
|
||||||
local clients = {
|
local clients = {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
do
|
||||||
local _print = print
|
local _print = print
|
||||||
|
@ -32,7 +30,10 @@ end
|
||||||
--Incoming packet.
|
--Incoming packet.
|
||||||
function server.Parse( packet, ip, port )
|
function server.Parse( packet, ip, port )
|
||||||
if not packet then return end
|
if not packet then return end
|
||||||
print( packet, ip, port )
|
if not clients[ip] then
|
||||||
|
clients[ip] = { ip = ip, port = port }
|
||||||
|
end
|
||||||
|
clients[ip].tick = packet
|
||||||
return server.Parse( udp:receivefrom() ) -- Process any packets we missed.
|
return server.Parse( udp:receivefrom() ) -- Process any packets we missed.
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ end
|
||||||
|
|
||||||
function server.Advance()
|
function server.Advance()
|
||||||
server.tick = server.tick + 1
|
server.tick = server.tick + 1
|
||||||
for id, client in ipairs( clients ) do
|
for id, client in pairs( clients ) do
|
||||||
udp:sendto( string.format("server: %d client: %d", server.tick, client.tick), client.ip, client.port)
|
udp:sendto( string.format("server: %d client: %d", server.tick, client.tick), client.ip, client.port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue