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 !

7 comments:

Michal Žugec said...

Great, it works! Tested on Beta3

Michal Žugec said...

And also works on Fedora9 ;-)
When I found some time, I'll write some howto + screenshots

Maya said...

Hi,

I am developing an app NCurses based app using yast2-libyui in c++. I need to replace part of my wiget tree. But I couldnt do it. Can u provide some ewxample. especailly I cant find ReplaceWiget method. I used recalcLayout method. but its taking lot of time. in documentation also use of that frequently discouraged.

Maya said...

I cant capture KeyEvents. Please can u provide an example.

kkaempf said...

Capturing KeyEvents must be explicitly enabled with the .set_send_key_events(1).

However, I've never tested this ...

Maya said...

I tried setSendKeyEvents( bool doSend ). but no luck. only selection box sending event for left, right arrow key presses.

I want to do following in my app (c++):

1. If user presses enter or return key when entering text in Input Field, I want to trigger some action in app.

2. I want to make navigation between widget items using arrow keys instead of tab or shift+tab keys. My dialog contains combo box, input field, buttons, selection box and table.

kkaempf said...

Hmm, if setSendKeyEvents() does not work its time to ask the libyui developers on yast-devel@opensuse.org.

Maybe someone there can come up with a complete C++ example which can then be used as a bindings example.