I’ve recently started a new hobby project/learning exercise in making a GUI framework with some goals in mind. It’s probably going to be a long side project and I thought it’d be cool to start a dev log; hey at least something to fill the blog :p.

My main goals with this project are:

  1. Re-build skill in lower-level programming. I’ve spent the majority of my time the past few years with Unity and other high-level frameworks or languages, and I think it’s important to review what’s going on under the hood.
  2. Practice and further learn a graphics API.
  3. Create a cross-platform GUI framework and later maybe make some apps or games with it.

Tools

  • C
  • OpenGL
  • GLFW
  • FreeType
  • Maybe a few others later…

I chose C for the goal of building up skill in lower-level programming. C’s lack of: a data stucture library, generics, inheritance, other OOP stuff, RAII, smart pointers, GC, etc…; forces you to focus more deeply on the low-level basics.

For the second goal. I started it off with OpenGL because it’s cross-platform (except maybe Mac now?) and not as extreme as the newer Vulkan. And the others are OS-specific and it would add a large amount more work supporting all of them.

GLFW provides a good platform-independence layer over core OS window creation, input events, etc. It might be better to call all the specific OS APIs here, but it’s not something I want to focus on right now. Also there’s still other places I need to do so anyway.

Text rendering is a whole other beast which FreeType greatly helps with. Regarding text and Unicode support, I’m starting off accepting UTF-8 but filtering to ASCII. After that I may move to support a larger limited set; not sure I’ll go full on Egyptian Hieroglyphs 𓂀, we’ll see. Apparently you can have multiple characters combine, and for that I may need a shaping library.

Later there’s also the audio. We’ll see about that later, maybe miniaudio idk. And video playback. One step at a time.

Current progress

So far the app is pretty basic, but it has some good features:

  • DPI awareness. The window and the contents appear the same when being dragged between monitors of different pixel densities. This is something some production applications and various open source libraries don’t do. I have a density independent unit type for specifying UI dimensions, and the font sizes respect DPI.
  • Multi-threaded. So far only a main event thread and a render thread. It might be good to spin off other threads dedicated for UI, simulation, etc. But we’ll see…
  • SDF Font Rendering. Thanks to FreeType. Good for 3D, but there may be better options for 2D screen UI. Planning to dive more into that later.

Progress on the UI front

Widgets:

  • Panel
  • Text Label
  • Text Button
    • Hoverable and clickable
    • Fires click callback on click
  • Edit Text Field
    • Text editing using piece table data structure.
    • Listen to unicode text input, but currently just filters to ASCII.
    • Cursor rendering with blinking animation.
    • Placing cursor where clicked on text.
    • Text selection and selection box rendering.
    • Left/right arrow key navigation. Ctrl key jumps between tokens.
    • Shift select.
    • Ctrl-A select all.
    • Copy/paste/cut.

General UI:

  • Cursor shape responds to element it’s over
  • Concurrent input event queues
  • Text alignment
  • Element alignment
  • Layout modes (none, vertical, horizontal)

That’s it for now, a boat-load more to do!