by Peter Kelly (critter)
The Notebook Widget
We've all seen this widget, or something similar, in action in some of the major applications, such as web browsers. We use notebooks on a daily basis, even if we didn't know that they were called notebooks. Now gtkdialog makes a similar feature available for us to use in our own applications. A notebook widget is a dialog with tabbed pages and each can be populated with other widgets.
Here's an example of its use, a five page photo album. While the photo album is of little use, it can be used as a template to construct something more practical by replacing the pixmap and text widgets on each page, and by adjusting the number and names of each tab.
Setting up the notebook widget is much like many of the other widgets I have shown. The tab-labels attribute, if omitted, defaults to Page 1, Page 2, … and the tab-hborder, tab-vborder attributes set the amount of space around the label in the tab. The page attribute sets the start up tab while the tab-pos attribute sets the position of the tabs on the notebook: 0=left, 1=right, 2=top and 3=bottom.
Below is the result of changing this value to 0.
There are many dialog utilities around such as zenity, yad and gtkdialog that allow us to create utilities that exactly meet our needs, and yet remove the tedium of having to code in a more complicated language such as C++. As these utilities become more complex, using several dialogs of various size and shape, they generate a disjointed appearance with dialogs opening and closing, often with a short delay between the closing of one and the displaying of the next.
The notebook widget can be utilized in these cases to give a more uniform and professional appearance. Placing the contents of each dialog to be displayed on its own page in a notebook widget, and turning off the visibility of the tabs and borders of all of the pages, and then displaying only the page that is currently required produces a seamless effect to the operation of the utility.
This next example shows this technique in action having a start page that allows the user to choose between a utility that simply displays the current data and time or a system backup routine that displays the pages that are relative to the previous selection. Although the example utilities are trivial and I haven't actually included any code to perform the backup routine, the mechanics of developing utilities with multiple screens is functional.
The Timer and Expander Widgets
The preceding example introduces two new widgets, the timer widget and the expander widget. The timer is a simple widget that is used in the example to update the time and date displays. The default delay is one second and the default unit is the second, but finer control can be had by including the tag attribute milliseconds="true" which will then use milliseconds as the unit. Here I have used two timer widgets, one with a delay of one second to update the time display, and the second with a delay of one hour (3600 seconds) for the date display. When the time expires the action is performed and the timer reset and started over.
The expander widget allows us to make more options available to the user but still keep the display uncluttered by only displaying those options that are more likely to be chosen. Clicking the expander displays or hides the additional options.
The example also introduces "conditional programming' in the code for page 2.
<action>if [ "$RB_2A" = true ]; then echo 3 > inputfile; fi</action>
<action>if [ "$RB_2B" = true ]; then echo 4 > inputfile; fi</action>
Here the variables assigned to the radio buttons are examined to see if they are "true' (selected) and if so then the action is performed otherwise the action is skipped. The action in this case is to write a new value to the file input file. The notebook widget is sensitive to this file so that when radiobutton RB_2A is selected the value 3 is written to the file and the notebook displays page 3 -- seamlessly.
Although the above code looks dauntingly long, much of it is repeated and heavy use was made of copying and pasting to produce it. To add a new page to the notebook, simply copy a similar page and paste it in the order where you want it to appear, and then add, remove and re-order the widgets on the page. This also has the advantage of maintain a consistent look throughout the application. Pages are not numbered per se but consist of all of the code enclosed in a "first order' container, that means a hbox, vbox or frame that is exactly one level below the <notebook></notebook> tags. This code may contain its own lower order container widgets. In the example, all of the pages are enclosed inside vbox widgets.
The List, Table and Tree Widgets
These three widgets are all similar, with the list widget being the simplest and the tree widget offering the most functionality. For comparison, here are some screen-shots of each using slightly modified examples from the gtkdialog documentation.
The list widget displays a simple, single column list of items for the user to select from. The scrollbars can be hidden if required, and other features such as height, width and title may be configured, as with most other widgets.
The table widget allows us to display multiple columns with optional, clickable and resizable headers, which allow for auto-sorting using various algorithms to allow for things such as letter case. The data may also be sorted on initialization. Auto-refresh is available for when the data-input file changes, and if auto sorting is enabled, then the data will be re-sorted.
The tree widget is rather poorly named, not generating a tree structure as we might understand it. It does however do all that the list and table widgets do, and a whole lot more. With the tree widget, we can icons improve the user interface and selection of multiple items is allowed.
When used in conjunction with signals, the built in functions, and the power of the bash shell, this becomes a versatile data selection widget.
Which of these widgets you should use depends upon what data you have and what interaction will be required from the user.
Combined with a little imagination, it is possible to assemble some useful tools using the gtkdialog widgets with only a little programming knowledge. Although the documentation for gtkdialog is rather sparse, a few searches on the internet -- or, a little bit of trial and error -- will usually bring results. There is quite a bit more to gtkdialog than I have demonstrated in these few brief articles, but the groundwork has been covered, and may have given you some ideas for projects of your own.