Tuesday, May 20, 2008

Declaring UI independence

Earlier this year, Stefan announced the availability of the YaST user interface engine separate from YaST itself.
The user interface engine, packaged in yast2-libyui (source code here),provides the abstraction from graphical user interfaces (Qt, Gtk) and text based (ncurses) user interfaces. It now can be used independently of YaST2 for generic (C++) applications.
Now what can you do with it ? First of all, you can use C++ to code YaST-like dialogs which display either in graphical mode (Qt or Gtk style) or text mode. This independence from the output media is a main feature of YaST.
Being separated from YaST, one can use the UI engine for stand-alone programs. A trivial example is a simple window with a text label and an 'Ok' button: HelloWorld.ccHelloWorld.cc Compile with
g++ -I/usr/include/YaST2/yui -lyui HelloWorld.cc -o HelloWorld
and run it via
./HelloWorld
Depending on the DISPLAY environment variable the UI engine automatically determines and loads the right plugin to render the dialog.
A simple unset DISPLAY will give you the ncurses look.

Enter SWIG

Coding dialogs in C++ takes away the highly useful edit-run mode of development which is possible with YaSTs YCP language.
With the help of SWIG, a generator for language bindings, one can now use his favorite programming language for coding dialogs. The initial release of the bindings supports Ruby (libyui-ruby), Python (libyui-python) and Perl (perl-libyui).
Swig can directly translate the C++ classes into e.g. Ruby classes making conversion of the above C++ code to Ruby straightforward: hello_world.rbhello_world.rb Translation to object-oriented Python gives you hello_world.pyhello_world.py Even Perl, although not object-oriented, gives reasonable code. But internals of the Swig-generated bindings are not for the faint-hearted ... hello_world.plhello_world.pl yast2-libyui comes with a couple of more examples.
SelectionBox1.cc shows how to fill a selection list, use buttons and update labels.
(SelectionBox1)
Here's the Ruby version: selection_box1.rbselection_box1.rb Enjoy !