local love = assert( love ) local lk = assert( love.keyboard ) local lg = assert( love.graphics ) local utf8 = assert( require 'utf8' ) local string = assert( string ) local _lt local _lkp local _lmm local _lmp local _callback local 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 textInput.width = 200 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 function textInput.keypressed(key, code, isRepeat) if activeWidget and textInput[code] then return textInput[code]() end end function textInput:clear() self.str = "" self.text:set( self.str ) end 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.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 return textInput