Zig NEWS

loading...
Cover image for IUP for Zig

IUP for Zig

Rafael Batiati
・3 min read

First of all, what is an IUP?

IUP (pronounced like "yup") in Portuguese stands for "interface do usuário portátil" or "portable user interface" in English.
It's a cross-platform GUI toolkit developed by PUC-RIO, the same university behind the excellent Lua language.

For more detailed information about IUP, please visit https://www.tecgraf.puc-rio.br/iup/.

My story using IUP

My first contact with IUP was between 2002 and 2003 when I was an undergraduate junior developer hired to work on a desktop application written in C, using IUP as GUI Toolkit.

I quickly got used to it and could manage to do a decent job writing user interfaces, but just a few months later the project manager decided to switch from IUP to Swing and rewrite the GUI in Java while keeping performance-sensitive parts in C.

Then, I started to write a bunch of JNI interfaces to be consumed by the Java side, and porting code from C to Java (oh, it was so 2000's 🙄).

After a while, I left the company, my life moved on, I worked on many other projects, but I never played with IUP again ...

Why bring it up now?

I first discovered Zig in 2020 and I was strongly motivated by the "better C" slogan, so I needed to try Zig on something I could measure how much better Zig is. When I realized that we hadn't any cross-platform desktop GUI toolkit for Zig yet, I checked on IUP after all this time and started putting things together.

As someone who has written the same user interfaces both in IUP and Swing, I think it wasn't IUP's fault, but the C language itself that didn't have the desired productivity tools after all. Time to give it another chance, but in Zig now! 🦎

The IUPforZig project

IUP is a solid and well-proven toolkit that exposes a simple raw C FFI, allowing me to focus on the library-binding design rather than on implementation details.

You can visit https://github.com/batiati/IUPforZig for more demos and details about the project.

IUP has dozens of GUI elements such as texts, buttons, calendars, panels, layouts, and so on, each accepting various attributes (value, size, color, alignment, etc) resulting in thousands of bindings to glue between C and Zig. Such an extensive API would be very hard to write and maintain by hand, so inspired by Marler's zigwin32 I came up with IUPMetadata, an attempt to collect rich information about each element and attribute in order to autogenerate the bindings code in idiomatic and type-checked Zig.

As IUP works mostly with name/value pairs ​​as UPPERCASE strings. while we can list programmatically all attributes, there is little information about the correct data type expected for its value (int, float, enum, struct, etc). The major part of the work consists in collecting those pieces of information and converting cases correctly, like "SCROLLTOPOS" to "ScrollToPos".

Snippets extracted from the original HTML documentation are rendered as doc comments on Zig code, providing quick access to API docs, improving productivity, and making IUPforZig more enjoyable to use. It can be even easier if you have Zls plugged into your preferred code editor 😍.

Integrated doc comments on VSCode

Here is a simple demo especially made for this post 🤓

Hello ZigNew on Windows Classic

Hello ZigNew on Ubuntu

And here is the source code:

// Compiles with Zig 0.8.1
const std = @import("std");
const iup = @import("iup.zig");

usingnamespace iup;

pub fn main() !void {
    try MainLoop.open();
    defer MainLoop.close();

    var dlg = try Dialog.init()
        .setTitle("Hi there!")
        .setSize(.Third, .Quarter)
        .setChildren(
        .{
            VBox.init()
                .setMargin(10, 10)
                .setGap(10)
                .setAlignment(.ACenter)
                .setChildren(
                .{
                    Label.init()
                        .setTitle("IUP FOR ZIG")
                        .setFontSize(32)
                        .setFontFace("Zig")
                        .setFgColor(.{ .r = 247, .g = 164, .b = 29 }),

                    Link.init()
                        .setTitle("We're on zig.news")
                        .setUrl("https://zig.news"),
                },
            ),
        },
    ).unwrap();
    defer dlg.deinit();

    try dlg.showXY(.Center, .Center);

    try MainLoop.beginLoop();
}
Enter fullscreen mode Exit fullscreen mode

Although IUPforZig is still a work in progress, for me it's already a great achievement to get my hands dirty in Zig and learn some of this fantastic programming language!

Discussion (1)

Collapse
kristoff profile image
Loris Cro

Congrats for publishing the first #showcase article on zig.news!