Ubit Home Page - Documentation Main Page - Examples and Tutorial
The following steps show how to create a simple text editor.
This section shows how to create a Ubit application. This application creates a main window that contains a multiline text editing widget (source code in file: sedit1.cpp)
#include <ubit/ubit.hpp> using namespace ubit; class SEdit : public UFrame { public: SEdit(); private: UTextarea textbox; // the text area widget UStr content; // the string contained in the textbox };
The first thing to do is to include the ubit header and tell the compiler that we will use the ubit namespace. We can now define SEdit, the main class of our application. It derives from UFrame which is the class for toplevel windows. SEdit have two variables.
These variables are not pointers but C++ "plain" objects (which means that the variables contain the object instead of pointing to it). These objects are automatically created and initialized when an instance of SEdit is created. This syntax is typical of C++ but does not exist in Java (we should use pointers and the new primitive to create each object). We'll see how to use C++ pointers in a safe way at a later stage.
int main(int argc, char* argv[]) { UAppli appli(argc, argv); SEdit sedit; appli.add(sedit); sedit.show(); return appli.start(); }The main() function performs the following actions:
SEdit::SEdit() { content = "Editable text"; textbox.add(content); this->addlist( uwidth(400) + uheight(300) + textbox); }
add(uwidth(400)); add(uheight(300)); add(textbox);It's purpose is to make the source code more compact. Note how the + operator is used to create the argument list that is given to addlist(). The only difference between add() and addlist() is that add() can only have one object as an argument.
addlist(uwidth(400) + uheight(300) + textbox);is just a shorter way to write:
add(*new UWidth(400)); add(*new UHeight(300)); add(textbox);
This example shows how to define widget properties such as the size, the scale, the font, the background and foreground colors, etc. (source code in file: sedit2.cpp)
We introduced the UWidth and UHeight properties in the previous section to specify the size of the main frame:
addlist(uwidth(400) + uheight(300) + textbox);First, it is important to notice that we can add properties to widgets by using the add() and the addlist() methods. In fact, these methods can be used to add almost any Ubit object to a widget
Second, a major feature of the Ubit toolkit is that widgets don't have properties of their own. This is very different from a toolkit such as Java Swing where most widgets have their own font, foreground and backround color, etc. Ubit widgets are just very ligthweithed "empty" containers. Their default appearence is specified by their style (each widget class is associated to a UStyle object that defines its appearance). Besides, graphical properties, such as the font or the foreground color, are often inherited from the parents of the widget (styles also define which properties are inherited).
This model is very similar to XML or HTML. For instance a <p> or a <h1> nodes have default apperances in HTML. This can be modified by changing their style or by adding attributes to them. Ubit widgets work exactly in the same way: to change a widget appearance, one can modify its associated UStyle or just add properties to it as in the following example:
textbox.addlist(UFont::bold + UColor::red + UBgcolor::yellow + content);This source code adds 3 properties to 'textbox'. They specify its font, its foreground color and its background color. UFont::bold, UColor::red and UBgcolor::yellow are predefined constants of the UFont, UColor and UBgcolor classes. Of course, we could also use instances of these classes as we did before with UWidth and UHeight; for instance:
textbox.addlist(ucolor("pink") + uscale(2.5) + content);which is equivalent to:
textbox.addlist(*new UColor("pink") + *new UScale(2.5) + content);Colors can be specified from predefined constants, color names or RGB values (see class UColor). The UBgcolor::none constant specifies that the widget is fully transparent. The UAlpha property controls its level of transparency. The UBackground property associates a background image or a pattern to the widget.
UScale is another interesting property which specifies the scale of the widget. Its argument is the magnifying factor that is applied to the object. A value < 1 reduces its size, a value > 1 increases it (note that this value should be positive).
Of course, properties can also be variables. This is what we are going to do now so that we will be able to change the properties of the 'textbox' widget interactively (this will be done in the next section when we see callbacks). Here is the new definition od class SEdit:
class SEdit : public UFrame { public: SEdit(); private: UTextarea textbox; UStr content; UFont font; UColor color; UBgcolor bgcolor; UScale scale; };And the new version of its constructor:
SEdit::SEdit() { content = "Editable text"; font = UFont::bold; color.set(255, 0, 0); // RGB spec bgcolor = UBgcolor::yellow; scale = 2.5; textbox.addlist(font + color + bgcolor + scale + content); addlist( uwidth(400) + uheight(300) + textbox); }Final remarks: Properties have many other interesting features:
textbox.addlist(font + color + bgcolor + scale + content); addlist(uwidth(400) + uheight(300) + textbox);
textbox.addlist(UFont::bold + UColor::red + "abcd" + UColor::blue + UFont::italic + "xyz");The rule is quite simple: properties take effect on whatever follows them in the list. This example also shows that a widget can contain several strings (strings can either be char* C strings of Ubit UStr strings).
This example shows how to define callback functions and callback methods Note that this example has an ugly layout. This problem will ne solved in the next section. (source code in file: sedit3.cpp)
The declaration of the SEdit class contains what precedes plus:
class SEdit : public UFrame { .... // same as above void setFont(UFont*); }; void showMsg(const char* msg) { cout << "message " << msg << endl; }setFont() ia a callback method that will change the font of the 'textbox'. showMsg() is a callback function that will print some useful message on the terminal. Here is the beginning of the new definition of the SEdit constructor:
SEdit::SEdit() { content = "Editable text"; textbox.addlist(font + color + bgcolor + scale + content); UBox& font_box = uhbox (UPix::edit + "Font: " + ubutton("Bold" + ucall(this, &UFont::bold, &SEdit::setFont)) + ubutton("Italic" + ucall(this, &UFont::italic, &SEdit::setFont)) + ubutton("Normal" + ucall(this, &UFont::normal, &SEdit::setFont)) );First, UBox& font_box = uhbox( ... ) creates a new UHbox object. UHbox is a horizontal box (UVbox is a vertical box). This expression is equivalent to: UBox& font_box = *new UHbox( ... ).
UBox& font_box is not an instance variable of SEdit but a local variable of the constructor, because there is no need to keep track of it after initialisation time. As for the addlist() method, The uhbox( ) shortcut function (and the UHbox( ) constructor) can take a +list as an argument. This +list contains:
ucall(this, &UFont::bold, &SEdit::setFont)means that: this->setFont (&UFont::bold) will be called when the button is activated.
UBox& color_box = uhbox (UPix::colors + "Colors: " + ubutton("Red" + uset(&color, &UColor::red)) + ubutton("Blue" + uset(&color, &UColor::blue)) + ubutton("Green" + uset(&color, &UColor::green)) );This piece of code is similar to the previous one except that we use the uset( ) construct. uset( ) is shortcut that calls the set( ) method of its argument. For instance:
uset(&color, &UColor::red)means that: color->set (&UColor::red) will be called when the button is activated. Obviously, this constructs will only work is the the first argument of uset() has a set() method. Note that we could also have use uset() in the previous case.
The last part of the SEdit constructor is:
UBox& event_box = uhbox (UPix::edit + "Font: " xxxxxxx + ubutton("Event test" + ucall(this, &UFont::bold, &SEdit::setFont)) + ubutton("Italic" + ucall(this, &UFont::italic, &SEdit::setFont)) + ubutton("Normal" + ucall(this, &UFont::normal, &SEdit::setFont)) ); addlist (uwidth(400) + uheight(300) + textbox + font_box + color_box + event_box ); }(to be continued)
Examples sedit4.cpp
and LayoutAndText.cpp shows how to create
editable text and how to specify simple layout constraints.
The main frame contains 3 parts: a tool bar, a text area contained in a scroll pane
and status bar.
These 3 elements are flexible in the horizontal direction. The scroll pane is
also flexible in the vertical dimension. These behaviors are specified by inserting
uhflex(), utop(), uvflex(), ubottom() in the child list of the UFrame.
The tool bar contains a text field with an editable string. This text is appended to the central text area when pressing the Return key or clicking the "Ok" button.