Skip to main content

skip to main content

developerWorks  >  Linux | Open source  >

GNOMEnclature: Getting ready for GNOME 2, Part 1

A look at what's ahead

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Introductory

Richard Hult (rhult@codefactory.se), Software engineer, CodeFactory
Mikael Hallendal (micke@codefactory.se), Software engineer, CodeFactory

01 Jan 2002

developerWorks is pleased to announce the relaunch of the Linux zone's popular GNOMEnclature column. In this incarnation of the column, Mikael Hallendal and Richard Hult of CodeFactory will give you the inside information you need to make the best use of the new GNOME 2 platform. In this series, you'll learn how to use the new and improved libraries available with GNOME 2 so that you can write your own Nautilus view, panel applets, and much more. In this article, Mikael and Richard reopen the series with a gentle introduction to GTK+ 2, the new foundation for the GNOME 2 desktop environment. By the end of this article, you'll have written and compiled a few sample GTK+ 2 programs and have a good understanding of GTK+ 2's many improvements over GTK+ 1.

About this series

Welcome to the new GNOMEnclature column! We're relaunching this column with brand new content to help you make the best use of the GNOME 2 platform. In the first few articles, we'll cover the differences between GNOME 2 and GNOME 1, so that your GNOME knowledge is fully up-to-date. These articles will be an ideal introduction for developers who want to start creating GNOME applications, and will also be of great assistance to current GNOME developers who need to port existing applications from GNOME 1 to GNOME 2.

First, we'll cover the basics. Then, once everyone has a good understanding of GNOME 2 fundamentals, we'll provide more in-depth coverage, showing you how to take full advantage of the cool new libraries available in the GNOME 2 platform. By the end of this series, you'll have written your own Nautilus view, created panel applets, and much more.

About this article

Because GNOME is built on top of GTK+, the best way to start this series is to describe the changes between GTK+ 1.2 and GTK+ 2. Therefore, in this first article, we'll take a look at GTK+ 2, giving you a brief description of the new widgets and the new ATK and Pango libraries that GTK+ 2 uses. Later in the series, we'll take a more in-depth look at the GTK+ 2 object system, as well as the two new widgets touched on in this article.



Back to top


Introducing GTK+ 2

Before we dive too deeply into the next generation GTK+, you're probably curious about when you can expect GNOME 2 to be ready for production use. GNOME 2 is scheduled to be released on 15 February 2002; the larger applications such as Gnumeric and Evolution will be ported to GNOME 2 some time after that.

OK, so let's move on to GTK+! GTK+ was originally developed to be used in Gimp (GTK stands for the Gimp ToolKit). GTK+ is currently available on a number of platforms including Linux and Windows. It's used by a tremendous number of free software projects, including GNOME itself, Mozilla, Gimp, and hundreds more.

Just like GTK+ 1, GTK+ 2 depends on GLib, which is a convenience library for C developers. GLib includes lots of nice functionality to make your programming work easier, including an object system and data structures such as hash tables, lists, and trees.

GTK+ 2 also depends on ATK and Pango. ATK is the Accessibility Toolkit, which enables people with disabilities to make use of GTK+ applications. Pango is a framework for rendering internationalized text. Both packages are described later in this article.



Back to top


Installing GTK+ 2

To get the most out of this article we recommend that you go ahead and get GTK+ 2 up and running. To install GTK+ 2, you should first ensure that pkg-config 0.8 or greater is installed on your system. All major distributions should have a package that provides pkg-config. Of course, GTK+ 2 also depends on external libraries, such as glib, atk, and pango. These libraries must be installed first before GTK+ 2 will compile. Generally, the best way to proceed is to first download the most recent versions of the glib, atk, pango, and gtk+ source tarballs (see Resources later in this article). Look inside the most recent "vx.y" directory you see, currently "v1.3".

You may find it strange that we've spent all this time talking about GTK+ 2, yet we are recommending you install GTK+ 1.3. There's a good reason for this: At the time this article was written, GTK+ 1.3.11 was the most recent version of GTK+ available. Once GTK+ is fully ready for production use, GTK+ 2.0 will be released. Until then, it's fine to use GTK+ 1.3 for testing, since it includes nearly all the new features that will be in the official GTK+ 2.0 release.

OK, now that we've cleared that up, it's time to get back to installing the new GTK+. Because GTK+ 2 has several build-time dependencies, it's important that you install glib first, followed by atk, pango, and gtk+. Install each package as follows:


Listing 1. Installing GTK+ and support library sources
                

tar xzvf package-version.tar.gz
cd package-version
./configure
make
make install

Once everything is installed, you should be able to start gtk-demo, a nice little program that lets you see GTK+ 2 in action.

So, what's new in GTK+ 2? One feature that lots of people have requested is the ability to use anti-aliased fonts with GTK+. This has now been added to GTK+ 2. GTK+ 2 font anti-aliasing is implemented using the Xft library and the XRender extension that is part of XFree86 4 and greater.

To enable anti-aliased fonts for GTK+ 2 applications, just set the environment variable GDK_USE_XFT=1. All GTK+ 2 applications started from that shell where GDK_USE_XFT is set to 1 should render anti-aliased text. If you want, go ahead and enable anti-aliased text, and then run gtk-demo again.


Example of a dialog using anti-aliased text
Dialog using anti-aliased text

Double buffering and image handling

Font anti-aliasing isn't the only graphical improvement in GTK+ 2; GTK+ now uses double buffering to update the screen. Due to a lack of double buffering, GTK+ 1 applications would sometimes flicker when redrawn or resized. GTK+ 2 no longer has this problem, so new GTK+ 2 applications will be rendered much more smoothly.

In addition to simply looking a lot prettier, GTK+ 2 offers a lot of improvements from the developer's perspective. For example, GdkPixbuf (previously a separate library) is now a part of GTK+. GdkPixbuf handles the loading and saving of images in various formats, such as GIF, PNG, JPEG, BMP, etc. Now that GdkPixbuf is part of GTK+, GTK+ itself can take advantage of it, using it to render alpha blended icons for menus, toolbars, and buttons.

Here's a sample GTK+ 2 program that loads a small image called gnome.gif:

Small bitmap image, gnome.gif

In our sample program, we create a GtkImage object using the gtk_image_new_from_file() function. The GtkImage object will load our image automatically, and makes internal use of GdkPixbuf to do so:


Listing 2. Using a GtkImage object to display an image
                

#include <gtk/gtk.h>

int
main (int argc, char **argv) 
{
	GtkWidget *window;
	GtkWidget *image;   

	gtk_init (&argc, &argv);
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	g_signal_connect (G_OBJECT (window), "destroy", gtk_main_quit, NULL);

	image = gtk_image_new_from_file ("gnome.gif");
	gtk_container_add (GTK_CONTAINER (window), image);

	gtk_widget_show_all (window);
        
	gtk_main ();
   	
	return 0;
}

Here's how to compile this simple program:

gcc `pkg-config --cflags --libs gtk+-2.0` -o image-button image-button.c

Once compiled, go ahead and execute ./image-button. This is what you should see:


fill in


Back to top


Pango

Pango is the new, all-singing, all-dancing framework for the layout and rendering of internationalized text. Thanks to Pango, GTK+ 2 is now much more useful for people who don't live in the U.S. or Europe. Pango can handle text that flows in a direction other than left-to-right and can manage complex languages with ease, even handling letters that take different forms depending on the context in which they are used.

Pango supports bi-directional text, so you can mix left-to-right with right-to-left text; there are also plug-ins for shaping various complex scripts like Arabic and Tamil. There's more to Pango than just internationalization; the Pango library handles the rendering of anti-aliased text with the help of Xft and the XRender extension. For more details, read two developerWorks articles about Pango (see Resources).



Back to top


Unicode and UTF-8

With GTK+ 2, any string passed to a gtk_*() function is expected to be in the Unicode UTF-8 encoding. By using UTF-8 internally, GTK+ 2 eliminates an entire class of internationalization problems with previous versions of GTK+.

Because ASCII is a subset of UTF-8, this change shouldn't make as much of an impact in existing GTK+ code as you might imagine. However, while ASCII maps directly to UTF-8, the reverse is not true. Many non-English character sets take up than a single byte per character when encoded in UTF-8. In order to handle larger than normal character encodings, you should now use a special function called g_utf8_next_char() (it's actually a macro) when you need to iterate over the characters in a UTF-8 string. This macro will take care of taking small or big byte "hops", as needed. Here's a small example, in which we validate and iterate over a UTF-8 string:


Listing 3. Validating and iterating over a UTF-8 string
                

gchar *p;

g_return_if_fail (g_utf8_validate (str));

p = str;

while (p) {
        gunichar c = g_utf8_get_char (p)
	
	/* Do something with c. */

	p = g_utf8_next_char (p);
}

If you need to convert a locale-encoded string to UTF-8, you can use:


Listing 4. Converting a locale-encoded string to UTF-8
                

gchar* g_locale_to_utf8 (const gchar *opsysstring,
                         gssize length,
                         gsize *bytes_read,
                         gsize *bytes_written,
                         GError **error);

The last three arguments can be NULL if you are not interested in how many bytes were read and written. If you are passing a NULL-terminated string to this function, set the length to -1; for example:

utf8_string = g_locale_to_utf8 (locale_string, -1, NULL, NULL, NULL);



Back to top


Atk, the Accessibility Toolkit

GTK+ 2 now makes full use of ATK, the Accessibility Toolkit. ATK makes it possible for people with disabilities such as impaired vision or limited mobility to interact with GTK+ 2 applications. In a future article, we'll cover ATK in more detail and show you how to make your own applications accessible to people with disabilities. You can visit the GNOME Accessibility Project in the meantime (see Resources).



Back to top


Stock items

Both GNOME 1 and GNOME 2 have support for "stock items", allowing developers to add common menu items and buttons to their applications very easily. Since stock items are defined globally rather than within the application, they make it easy to provide a uniform look across all GNOME applications.

Typically, an individual stock item consists of an icon, a text label, and an optional accelerator key. In addition to giving applications a uniform look, stock items are also a great help for internationalization since they only need to be translated once (in the GTK+ library), rather than having application-specific data that needs to be translated by the individual developer. For the GNOME 2 platform, stock item support has been moved from gnome-libs to GTK+, making it possible for even more applications to have a consistent look and feel.

Here's a snippet of example code that creates a button with a floppy disk image and a "Save" label:


Listing 5. Creating a button with a floppy disk image and a "Save" label
                

GtkWidget *button;

button = gtk_button_new_from_stock (GTK_STOCK_SAVE);

Here's is a screenshot showing a toolbar using four stock items:


Toolbar using four stock items
Screenshot of a toolbar using four stock items

Stock items can also be used in menu items, as follows:


Listing 6. Creating a menu item with a floppy disk image and a "Save" label
                

GtkWidget *menu_item;

menu_item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE);

This code creates a menu item with a floppy disk image and a "Save" label. It also automatically connects the Ctrl+S keyboard shortcut to the menu item. Using stock items ensures that Ctrl-S will always be the default save shortcut, no matter what program you happen to be using.

If there is a suitable stock item available, it's highly recommended that you take advantage of it to create your menu items, toolbars, and buttons. Not only will you make your user interface more consistent, but you'll also save precious time and lines of code.

You can also create stock items locally in your own application. This can save time and code if you need to use the items in several places, and it also makes your icons thematic.



Back to top


Markup

With GTK+ 2, it's a lot easier to use different fonts, sizes, color, and styles when specifying text widgets. This new functionality is possible thanks to Pango, which now supports a small markup language called GMarkup. GMarkup is a lightweight XML-like syntax that allows you to specify different text styles by simply embedding tags into the strings that you provide to various gtk_*() functions. Here's an example:


Listing 7. Pango markup example
                
  
#include <gtk/gtk.h>

int
main (int argc, char **argv) 
{
        GtkWidget *window;
        GtkWidget *label;
        gchar     *markup_text;
                
        gtk_init (&argc, &argv);
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        g_signal_connect (G_OBJECT (window), "destroy", 
                          gtk_main_quit, NULL);

        label = gtk_label_new ("A <span color=\"blue\">blue</span> 
                          <big>and</big> <b>bold</b> label");
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

        gtk_container_add (GTK_CONTAINER (window), label);
        gtk_widget_show_all (window);
        
        gtk_main ();
      
        return 0;
}

And to compile:

gcc `pkg-config --cflags --libs gtk+-2.0` -o label-markup label-markup.c

The code example, when run, will look like this:


Pango markup
Pango markup


Back to top


Keyboard navigation

GTK+ 2 makes it much easier to create a user interface that's easily accessible using only the keyboard, thanks to several new features. First, switching focus between different widgets is now more predictable than in GTK+ 1. Just use Tab and the arrow keys and everything will work as expected. Second, GtkDialog, the new dialog widget, automatically handles the Escape key and closes the dialog. Third, it's now very easy to create keyboard accelerators, also known as mnemonics. To create a button with a mnemonic, simply do this:

button = gtk_button_new_with_mnemonic ("_Quit");

The button can then be activated by pressing Alt+Q. The character that is preceded by an underscore will be underlined, indicating that it represents a keyboard shortcut.

Here's an example showing the use of mnemonics for notebook pages and buttons:


GTK+ 2 mnemonics example
                

#include <gtk/gtk.h>

int
main (int argc, char **argv) 
{
	GtkWidget *window;
	GtkWidget *vbox;
	GtkWidget *label;
	GtkWidget *page;
	GtkWidget *notebook;
	GtkWidget *button;
	
	gtk_init (&argc, &argv);

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        g_signal_connect (G_OBJECT (window), "destroy", 
                          gtk_main_quit, NULL);
	gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);

	vbox = gtk_vbox_new (FALSE, 0);
	gtk_container_add (GTK_CONTAINER (window), vbox);

	/* Create our notebook and two pages, with mnemonics. */
	notebook = gtk_notebook_new ();
	gtk_box_pack_start (GTK_BOX (vbox), notebook, TRUE, TRUE, 0);

	label = gtk_label_new_with_mnemonic ("Page _1");
	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), 
	                          gtk_label_new ("Page one"), label);
	
	label = gtk_label_new_with_mnemonic ("Page _2");
	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), 
	                          gtk_label_new ("Page two"), label);

	/* Create a button with a mnemonic as well. */
	button = gtk_button_new_with_mnemonic ("_Quit");
	gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, TRUE, 0);

	/* Make the quit button actually quit. */
	g_signal_connect (button, "clicked", gtk_main_quit, NULL);

	gtk_widget_show_all (window);
	
	gtk_main ();
        
	return 0;
}

To compile:

gcc `pkg-config --cflags --libs gtk+-2.0` -o mnemonics mnemonics.c

Note the mnemonics in the resulting image:


GTK+ mnemonics
GTK+  mnemonics


Back to top


GtkTreeView

GtkTreeView is a new tree and list widget that replaces GtkCList and GtkCTree. In the past, there was poor logical separation between data and view, and it was difficult to write custom cell renderers. With GtkTreeView, these problems have been resolved. As a bonus, GtkTreeView has an editable text cell, and features animated expander arrows for a bit of eye candy.


GtkTreeView in action
GtkTreeView in action


Back to top


GtkTextView

The new GtkTextView widget is a huge improvement over the old GtkText widget. It has a lot of nice features:

  • It supports the use of mixed fonts, styles, and text colors, and you can set line spacing and adjustment on a line-by-line basis.
  • Since all text is represented in UTF-8 and rendered using Pango, GtkTextView is fully internationalized.
  • Long lines can be word-wrapped or by wrapped by character if preferred.
  • You can embed images, and even other widgets.
  • Since GtkTextView uses a Model/View/Controller design, it supports multiple views of the same text buffer.

Here's what the new GtkTextView widget looks like when rendered:


GtkTextView in action
GtkTextView


Back to top


Conclusion

Now that we've taken a good look at the new functionality available in GTK+ 2, we're ready to start exploring the rest of the GNOME 2 platform. Please join us in our next article when we take a look at the new Glib-2 object system. See you then!



Resources



About the authors

Richard Hult works for CodeFactory and has been a GNOME developer for about three years. At CodeFactory, Richard maintains MrProject, a GNOME project management application. Richard is also the author and maintainer of Oregano, a GNOME circuit design application.


Mikael Hallendal is a GNOME developer for CodeFactory in Sweden, currently working on MrProject, a GNOME project management application. In addition, Mikael is developing a help browser for GNOME 2.0 called "Yelp", and is also maintaining DevHelp, a document browser for developers. As if that weren't enough, Mikael also serves as the Desktop Team Leader for Gentoo Linux.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top