dburrows/ blog/ entry/ from-blogspot/ ANNOUNCE: cwidget

I've just uploaded the first release of libcwidget to Alioth and NEW. libcwidget is a high-level C++ library for developing user interfaces that run in a terminal using curses as the display and input layer. It uses widget abstractions similar (but of course not identical) to those found in GTK+ and Qt, with signals and slots provided by libsigc++.

Background

Back when I started writing aptitude, I had one general goal:

Just because it runs in a terminal doesn't mean it has to suck.

I tried to apply this in the user interface, but I also applied it internally. The curses programs I looked at before writing aptitude all had very ad-hoc UIs. In many cases the code was structured with each "view" that appeared mapped to a custom C function call; if the author was feeling ambitious, similar-looking screens might be abstracted into a single function call, but the basic structure of the interface still reflected the call graph of the program.

aptitude had a primitive interface abstraction layer from the get-go; over the years, I borrowed ideas from GTK+ and restructured this layer into a full widget set. libcwidget is this code, disentangled from the guts of aptitude and slightly cleaned up. Because of its history, it is missing widgets that aptitude doesn't need (like a multi-line text editor), but it provides an extensible base that you can build upon.

Getting cwidget

The cwidget library is available (both as source and as an i386 .deb) from the cwidget Alioth releases page. There is also API documentation automatically generated from the upstream repository, which, while it is woefully incomplete, should provide some information: I've tried to write Doxygen tags into most of the code I've added in the last 4 years or so.

The upstream code repository is in git (because what fun is a new project if you don't learn a new VCS?) and available here. To retrieve a copy of the repository for yourself, run this command:

git clone git://git.debian.org/git/cwidget/head cwidget

Comment by ak at 12:54 AM:

Although a C++ developer by myself, I find your language choice the greatest disadvantage. That's why I'll stick to STFL, which doesn't only support C/C++, but also Perl, Python, Ruby and SPL.

Comment by dburrows at 7:36 PM:

I hadn't heard of STFL before, thanks for the link. I certainly am not claiming that cwidget will solve all the world's curses problems: aside from anything else, it's newly yanked out of the aptitude source code and needs some love before it's a truly general library.

At a quick glance, I think the libraries compare like this:

Features SFTL has that cwidget doesn't:

Features cwidget has that SFTL doesn't: * A proper top-level main loop; you don't have to structure your program as a sequence of input "screens". * A defined threading model and support for injecting events from background threads to foreground threads. * Support for defining your own custom widgets at the same level as the predefined widgets. * Events are handled using signals and slots. * Support for laying out structured and styled text. * Support for overlapping widgets. * Widgets for drop-down menus and hierarchical trees. * The ability to dynamically hide and show widgets, and dynamically manipulate them in other ways (e.g., scrolling around a text view or replacing the text in it). * It's a C++ library.

In general, it looks to me like cwidget and STFL are solving different problems. STFL aims to be a library for presenting forms on the terminal that are more complicated than you can do with dialog. This is a fine goal and frankly probably one that's useful to more people than what cwidget provides (as you pointed out). cwidget is a backend for applications that have a moderately complex UI: programs like mutt, links, emacs and mc. I think there are something like three people still writing new code for this sort of program, and two of them don't know C++, so the audience is rather limited. ;-)

If I had an infinite amount of time and nothing to do but develop cwidget, I think that it would be interesting to provide bindings to other languages and even more interesting to have a UI description language. But since I have a finite and limited amount of time, I think I'll worry about making the documentation not suck first and plugging the gaping holes in the set of standard widgets that it provides. :-)