InputField - proper text input handling library

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

InputField - proper text input handling library

Post by ReFreezed »

InputField enables simple handling of user text input into your program. The library is a single file with no external dependencies.

Features:
  • Different field types: Single-line, multi-line (with or without wrapping), password (obscured characters).
  • Text cursor and navigation (by keyboard and mouse).
  • Text selection.
  • Scrolling, both vertical and horizontal.
  • Text alignment.
  • Shortcuts for common operations, like copying selected text and deleting the next word.
  • Undo and redo (history).
  • Helper functions for rendering.
The library does not do any rendering itself, but provides helper functions for rendering text, cursors and selections.

InputField on GitHub Image
Direct link to library file
Releases
Example programs

Basic usage:

Code: Select all

local InputField = require("InputField")
local field      = InputField("Initial text.")

local fieldX = 80
local fieldY = 50

love.keyboard.setKeyRepeat(true)

function love.keypressed(key, scancode, isRepeat)
	field:keypressed(key, isRepeat)
end
function love.textinput(text)
	field:textinput(text)
end

function love.mousepressed(mx, my, mbutton, pressCount)
	field:mousepressed(mx-fieldX, my-fieldY, mbutton, pressCount)
end
function love.mousemoved(mx, my)
	field:mousemoved(mx-fieldX, my-fieldY)
end
function love.mousereleased(mx, my, mbutton)
	field:mousereleased(mx-fieldX, my-fieldY, mbutton)
end
function love.wheelmoved(dx, dy)
	field:wheelmoved(dx, dy)
end

function love.draw()
	love.graphics.setColor(0, 0, 1)
	for _, x, y, w, h in field:eachSelection() do
		love.graphics.rectangle("fill", fieldX+x, fieldY+y, w, h)
	end

	love.graphics.setColor(1, 1, 1)
	for _, text, x, y in field:eachVisibleLine() do
		love.graphics.print(text, fieldX+x, fieldY+y)
	end

	local x, y, h = field:getCursorLayout()
	love.graphics.rectangle("fill", fieldX+x, fieldY+y, 1, h)
end
See the library file for documentation. Also look at the example programs.
Last edited by ReFreezed on Thu Aug 18, 2022 2:06 pm, edited 10 times in total.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: InputField - text input handling library

Post by pgimeno »

Not providing rendering is a quite radical approach. I like it :)

Nice work. It's not often that you see so much love placed in an edit control. Almost all fall short of standard features. Slab and Thranduil were the closest to full features editors I've seen before this one, and both missed on some.

I've found a problem. Double-click to select word does not work well in presence of multibyte characters, and it appears that it doesn't work well when using Ctrl+Arrow either, so maybe it's about the word splitter. As for features, it's pretty complete, congrats! In my tests I only missed the double-click-and-drag feature to select multiple words, and the Shift+Del key combination as equivalent to Ctrl+X.
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: InputField - text input handling library

Post by ReFreezed »

Thanks for the feedback, pgimeno!

Because rendering tend to be different in every game/GUI system I thought having a lower-level library like this would be good for handling text input as it's more portable. (I've actually used a version of the library for several years in multiple different projects and it's been working nicely.)

Yeah, word navigation was broken (fixed in repo). I noticed utf8.codes() generates garbage after I did most testing so I hastily implemented my own version (very incorrectly). Also, the library doesn't support non-ASCII punctuation and whitespace yet - it sees all non-ASCII characters as letters. It'll be fixed soon.

I'll add double-click-and-drag and the missing shortcut to the todo list.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: InputField - text input handling library

Post by ReFreezed »

Update 3.1

Changes since 3.0:
  • Added double-click-and-drag to select words.
  • Added shortcut Shift+Delete to cut text.
  • Pressing Escape while dragging stops the dragging.
  • Fixed word navigation/selection not working.
  • Better Unicode support for word navigation/selection.
  • Fixed freezing issue when calling some methods on fields that never had any text.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
togFox
Party member
Posts: 764
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: InputField - text input handling library

Post by togFox »

Incorporating 3.1 into my project. Works v well. :)

Is there a way for the inputfield to not have focus all the time? I see the 'cursor' is always on and when I use arrows to move through the text, those same arrows are scrolling the map I have in the game.

I want my arrows to either: a) scroll the map when the input box does not have focus or b) manipulate the cursor in the input box when it does have focus. Do I need to capture mouse clicks and track focus myself and then govern different actions in love.keypressed? I assume so - and that's okay. Just trying to nut this out.

I get this is a 'low level' library that requires extra work and I'm happy to do that extra work. Also, how does the cursor respond if you have multiple inputfields? Must try ...
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: InputField - text input handling library

Post by ReFreezed »

Yeah, focus is something you'll have to implement yourself. Example for key handling:

Code: Select all

local fieldHasFocus = false

function love.keypressed(key, scancode, isRepeat)
	-- First handle keys that override InputField's behavior.
	if key == "tab" then
		fieldHasFocus = not fieldHasFocus
		field:resetBlinking()

	-- Then handle InputField, if it has focus.
	elseif fieldHasFocus and field:keypressed(key, isRepeat) then
		-- Event was handled.

	-- Lastly handle keys for when InputField doesn't have focus or the key
	-- wasn't handled by the library.
	elseif key == "escape" then
		love.event.quit()
	end
end

function love.textinput(text)
	if fieldHasFocus then
		field:textinput(text)
	end
end
Every InputField instance have their own cursor and everything - i.e. instances are independent from each other.
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
togFox
Party member
Posts: 764
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: InputField - text input handling library

Post by togFox »

Okay. Thanks. I might have multiple input fields so I'll try moving that focus thing inside the field to keep that tidy.

field:hasFocus(boolean)


and then set that value in mouse press events.

I haven't checked the code but that should be straight forward.
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: InputField - text input handling library

Post by ReFreezed »

If only one field has focus at a time it might be preferred to, instead of having a boolean 'fieldHasFocus', have a global 'focusedField' that determines what field has focus (nil could mean nothing has focus). That way you don't have to update the internal state of several instances when focus changes.

Code: Select all

function love.keypressed(key, scancode, isRepeat)
	-- ...
	elseif focusedField and focusedField:keypressed(key, isRepeat) then
	-- ...
end

Code: Select all

if someField == focusedField then
	-- someField has focus!
end
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
User avatar
togFox
Party member
Posts: 764
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: InputField - text input handling library

Post by togFox »

Yeah - I thought about that after posting. And set it to nil if no field has focus. Thx.
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
User avatar
ReFreezed
Party member
Posts: 612
Joined: Sun Oct 25, 2015 11:32 pm
Location: Sweden
Contact:

Re: InputField - text input handling library

Post by ReFreezed »

Update 3.2

Changes since 3.1:
  • Added text alignment (left/right/center).
  • Added methods: canScroll, canScrollHorizontally, canScrollVertically.
  • Added methods: getScrollHandles, getScrollHandleHorizontal, getScrollHandleVertical.
  • PageUp and PageDown work in multi-line fields.
  • Keyboard interactions are now disabled while dragging.
I've also added another example program to the repository. (See the new examples folder.)
Tools: Hot Particles, LuaPreprocess, InputField, (more) Games: Momento Temporis
"If each mistake being made is a new one, then progress is being made."
Post Reply

Who is online

Users browsing this forum: No registered users and 14 guests