text box advice

hey fellas,

edit: I changed my mind. I just want the player to type their name. I’ll just do the dumbest possible: accept only A-Z, space and backspace, no bullshit. if you have knowledge to share, I’d like to hear anyway.


uuuuh look I didn’t research much, but I want to make a text box in SDL2. something very simple, I don’t want to handle right-to-left text, but I will need to deal with accented vowels áàéíõã and çÇ.

so yeah there is all those functions described in SDL2/Tutorials-TextInput - SDL2 Wiki

but I don’t really get it. like, I don’t know what am I responsible for, what SDL does for me, and what the platform does for me.

the cursor. who draws the cursor? me? who moves the cursor around? if the user presses END, HOME, arrow keys, CTRL, clicks on the text box, who moves the cursor?

what about selection? do I paint the selected text? or does the system paint it?

how about deletion. do I handle deletion of characters?

I mean, if I do stuff, how will the system know I did those things? or maybe it doesn’t need to know and all works fine?

is there some library that could help me do those string operations? like, delete UTF-8 characters easily, iterate over characters etc.

also. I know that text boxes are one the hardest things to implement, and there are super complicated algorithms to handle all corner cases. like that one Firefox blog post where they detail their strenuous attempts to get it right: Text Rendering Hates You - Faultlore

finally. I haven’t sat down to write code, maybe when I do things will make sense. but so far I’m scared and hesitant

Happy to step you through it if you want to post your attempts, here’s a couple of things to get you started:

  • Head over to Google Fonts to download any font you want and unzip it into your project resources folder. I usually get Roboto by default, and I change the file name to roboto.ttf to save time.
  • Make sure to turn on the text editor events using SDL_StartTextInput before the game loop. (Or after the user selects the text-texture’s hitbox)
  • Grab events of the type SDL_EVENT_TEXT_INPUT
  • Display the text typed using the SDL_TTF library
  • You will eventually want to grab events for backspace and left/right keypad presses, but just start by getting strings output as the user types.

I’m hoping you are OK with C++, because std::string and class/objects will save a lot of headaches.

1 Like

I’m writing a GUI library, I can say, if just typing in letter and drawing it on screen works, do that (like your edit suggest), it’s 1000x simpler than what I’m writing and I had no issues with that until I wanted a high quality GUI

1 Like

There is a complete editbox example using SDL_ttf here:

If you need to implement the simplest possible editbox, i.e. just adding new letters at the end of the text and deleting them with backspace, you can implement this even on keypress events, without using SDL_TextInput. This is the simplest, but also the most primitive - including the ASCII limitation.

If you care about UTF-8 support, the only sensible solution is to use SDL_TextInput. In addition, you will have the option to support candidates and text composition. If you want to know more, the best source of information is the example linked by @slouken above.

A third option is to use the SDL_TextInput feature to have UTF-8 and candidates support, and implement the text composition yourself if you need more control over the caret and selection. In this case, text entry is based on SDL_EVENT_TEXT_INPUT events, while caret and selection manipulation is based on SDL_EVENT_KEY_DOWN events. You handle the information about the caret position and the selection yourself, and you place new text data from events in your character buffer by inserting it in place of the caret or selection.


I use the third option for my engine’s edit fields. Not only do I have UTF-8 support and full caret and selection control, but I’ve also added character filtering (e.g. limiting characters to digits), the ability to limit text length (taking into account UTF-8 codepoint sizes), animated caret and so on. To render text, I use my own font format (very simple, dedicated to pixel art), so I can render text in one font (e.g. white letters without background), and the selected fragment in another (e.g. transparent letters with a background of any color). I still have to add candidate support, but it’s not a priority at the moment.

Implementing such an edit field takes about 1000 lines of code, including just collecting and modifying the text, handling caret and selection, text length limit and character filters (without rendering).


If you need something more advanced, you’ll have to write hundreds of lines of code. But the beauty of it is that SDL provides support for text entry and provides all the necessary data in events, but how you use it and how you render the text is entirely up to you. This way you can implement the edit field the way you want, without imposing anything (including the appearance of the edit field and text, like controls from Win32 API do).

Ideally, and of course depending on your market, you will also want to support right-to-left written languages (such as Hebrew) and complex scripts (such as Arabic). This complicates things somewhat, but now SDL_ttf includes Harfbuzz it’s not all that difficult and I have successfully implemented both in my app.

I’m programming a pixel art game, not the new Microsoft Word. :wink:

I care more about the main languages, but in case I need left-to-right support, it’s very easy to implement — it’s literally a few lines of code to add. It all comes down to reversing the operation of the caret movement and selection keys (e.g. Left works like Right, Home works like End, etc.). And the left-to-right can also be used for bottom-to-top languages — this is just a matter of glyph rendering direction.

Text rendering for me will remain as simple as it was, because it’s just a blit of glyphs from the atlas to the target, one next to the other, in a given direction and with known spacings. I don’t support kerning, because it’s unnecessary in the case of pixel art.

For now I have implemented a set of functions for rendering horizontal text, but adding left-to-right support and vertical text is also quite easy. I haven’t implemented it yet because I don’t know if I’ll ever use it (especially vertical text), and writing code just to sit unused is not a good idea.


Anyway, that’s why I like to implement such subsystems myself instead of depending on other people’s libraries, because the whole implementation is mine, only the features I need are added, and if I want new ones, I can add them without a problem, because I know mu code by heart. Full freedom.

I’m not talking about the complications of a Word Processor, that’s a totally different ballgame. For example I wouldn’t expect you to support mixing text in different scripts and directions (something I do have to do).

But even the simplest text input box, for example to enter your name, needs support for complex script languages if it’s going to be used by somebody whose native language is written that way.

That means, for example, that you cannot simply “blit glyphs from the atlas to the target, one next to the other, in a given direction and with known spacings”. Fortunately SDL2_ttf (with Harfbuzz) does most of the hard work for you.

I agree that multiple language support is important for broadening your audience, but I think Elefantinho was wanting day-one type help:

I don’t want to just blurt out code, this is a complicated topic and it should reflect your thought process, your coding skills, and your style.
The main problem that I think someone will face at this point is that there are so many ways that feature creep can put you into analysis paralysis.
Just get started.
Don’t worry about supporting every feature under the sun, just build to suit the current problem.

@elefantinho : Please share your code and/or ask questions about what you are trying to implement, we’re here to help you. What step are you at today?

1 Like

No, the simplest textbox, e.g. for entering name, does not have to use SDL_TextInput and UTF-8 at all. The simplest way is to handle SDL_EVENT_KEY_DOWN events and convert scancode to ASCII letter, using SDL functions designed for this purpose. Changing the caret position or handling the selection is not required.

Many beginners use this method, because it is trivial to implement and everyone, regardless of operating system’s language, is able to enter such ASCII characters.


I know what you want to convey and I fully agree with what you wrote in previous posts (except that I have to use e.g. HarfBuzz to correctly support e.g. Arabic, which is not true). However, your suggestions are intended for those who actually need a professional tool and the widest range of possibilities.

my only worry is portuguese and english. I’m writing an acrostics generator program. everything is written in C. so I have a collection of words in english and portuguese, and the user inputs a small phrase to fill up randomly.

I have many worries in my mind, such as handling Unicode, and doing a GUI that is responsive, so I spent my time looking at GUI things, and tonight I will try to compile this library called LVGL, which refers to their SDL backend merely as a “simulator” and sees their Emscripten backend merely for the purposes of “online demo”. it comes with a textbox “widget”, and I will use their “button matrix” as a virtual keyboard for my Emscripten port. their online demo of textbox erases text when I input accented vowels or çÇ using my keyboard, but I think it is worthwhile to try, maybe I can patch their port, or I can intercept SDL keyboard events directly and write to a “label” widget myself.

I also tried a GUI library called clay, it is easy to compile and I got their SDL example working right away, but it is kinda buggy and the Emscripten version flickers when resizing the window. LVGL demos are way too attractive and robust, so I’m going for it.

I appreciate all the input so far, it is a lot of useful knowledge I will keep in mind and revisit as I face problems!

hey guys, I managed to compile and use LVGL, however pressing issues will keep this small endeavor in hold. thanks for the feedback, I will remember this thread’s existence in my heart and revisit it once I find able time to work more

A better place to remember this thread is in bookmarks. :wink: