After I have managed to build the most basic assembly raylib web app, I started to mess around with the raygui as well, hopefully to have a little, lightweight, lean gui library covering all the fundamental components, and on the way of learning this library, there are a little twist because I didn’t manage to get the library works in one go for web assembly, and there were some build issues; meanwhile, I know raylib works, so… I decided to reverse engineering the raygui library so that I can build some of the components for my future projects, which is a both right and wrong decision.
“Just rendering some rectangles and texts, how hard can it be?” For some of the components, by principle, are not difficult, but there are much more different factors resulting in a good or a bad implementations.
Starting from building a button, which is the simplest component. Fundamentally, they are just 5 rectangles lumped together which four rectangles forming an edges at the sides of the center one, along with a simple event detection, changing the state of the button and return a signal to control other part of the application.
However, how to properly plot 5 rectangles in a way that the borders are in the correct location? After I have reverse engineering the library for printing the rectangle, I find it both complicated yet fascinating as someone who is a beginner in learning lower level of gui libraries. To draw rectangles surrounding to the middle rectangle, we need to know the offset after an edge is applied and the thickness of the border. Since the size of the rectangle and border are dynamic, we can’t calculate with a hard coded constant because the shape and the ratio will be distorted if the resolution is changed, and the border won’t be customizable in terms of their style.
With all those carefully calculated value, we finally have a rectangle, but… how can we change the style of the rectangle such that different events change change style? This is definitely a wild adventure because it has so much just to have a flexible and efficient way to change the style of the button. Every styling is started from a single lookup array, uniformly partitioned by the number of components with fix number of properties like the alignments, coloring and texts configurations.

Extracted from the original raygui library – line 1405
For a frequently used lookup for a low level part of the library, this is a great decision because array has the fastest lookup time comparing to other data structure that require iterations or extra calculations on lookup, while the number of components and properties are constant throughout the life time of the program which there is no insertion operation that will slow down the library, resulting in a performant design which getting and setting the style can be done with O(1); nevertheless, since arrays are accessed using numerical index, that can be unintuitive, but they did an interesting trick to solve the issue, by using enums:

Extracted from the original raygui library – line 515
I found it interesting because I never use enum and I had no idea what is the point of having a structure that has a list of value, but now I have finally see its merit because with enum with defined numerical value, it is possible to index the array using the defined keyword, indexing the array with keyword similar to a hashmap yet it is no overhead on the computation:

Extracted from the original raygui library – line 4249
The examples and illustrations above are from the original raygui library written by raysan5, but how about my attempts on recreating these features? Well, despite having a working design, I did have some hurdles on recreate similar features in zig, but these hurdles makes me know more about zig and the library in general, so let me point out some of the valuable ones:
Starting by creating a button, the principle are simple, by handling the mouse input events if it is within the range of the rectangle that represent the button, using CheckCollisionPointRec(point, rec), to prevent any click event triggers outside the button. After that, based on the original source code, I need to handle click event, and I was puzzled about two particular functions, IsMouseButtonDown() and IsMouseButtonPressed() which they have similar behavior, but after some experimentation, it turns out IsMouseButtonDown is level triggered which it is true when the button is pressed, while IsMouseButtonPressed is edge triggers which it only return true right at the moment the mouse button is pressed, creating a pulse instead of a constant value. The difference of these two event detection are important because we want to have a button that visually, it can let user know they have pressed or hold the button, but it only send a short pulse to prevent a function engaged by the button triggered multiple times. By implementing such a simple element, it really helps me to know more about how the functions in raylib works.
To render a button, I needed to render all the rectangle, and since I was inspired by the raylib design, I tried to use enum for calculate the index for styling; however, I did a pretty bad mistake due to the lack of idea of how strict the type in zig. Because I normally think that indexing in array is always in positive, I have use unsigned integer for the enum, meanwhile the coordination are float based, and the function call are integer. As a result, I ended with the following “Master Piece”!


Haha! Look at my mess! Yoyo code are everywhere.
They bad in a hilarious way because I have to frequently casting floating point into a c_int and zig integers back and forth, not to mention the addition cast between enum, unsign and signed integer. Although some of the problems are belongs to the dependency I was using, which they bind with c integer instead of using the native zig one, this helps me to understand how I should plan my project in terms of the choice of variables and how I should build a binding if I have a C library on hand. It is not wrong to think indexing only occur in positive, but if I need to do calculation with other values, it is better to stick with integers. Besides, if I were the one who create the binding from C libraries, I should think of a more idiomatic way to build the bindings in a way that I shouldn’t cast any C integers from my application layer; thus, I should have an interface that converts C type into zig. If I had adopted all the suggestions above, I could definitely reduce majority of unnecessary castings, to get rid of the yoyo code problem that hurts the readability. Thus, this actually helps me on how to write better code by observing the mistakes the one who creates the binding and I have made.
With all the time spent in the project, I have finally been put into a halt on my way on the reverse engineering because I just realized that some of the components, especially the one that includes text, they have so much code that are used for handling edge cases, this makes me realized that it is actually not realistic to re-implement some of the components due to the complexity. Thus, I decided to go back to the original template project that cause an error in the raygui dependency injection, and it turns out… the problem was just I didn’t write to code in a zig way, by declaring the rectangle component by using the init function. After that, I just learnt that most of the time, perhaps it is me misunderstood how the library and zig work, rather than the problem of the library.
After I have more understanding to the library, my original intention has gone away which I no longer need to reinvent the wheel, and at the same time, after reading the original raygui library, now I have a respect to people who write gui libraries because there are so much works just to handles all the edge cases and to make the library versatile and performant; besides, although reverse engineering a gui library might be a mistake, this actually makes me learnt a lot more in programming, coding practice, the tools I am/will use, and because of that, I think I have more confidence to work on my first actual web app, so stay tune!