Writing a GtkWidget

Table of Contents
Overview
The GtkWidget Base Class
An Example: The GtkEv Widget
GtkWidget In Detail
GtkVBox: A Windowless Container
GnomeAppBar: A Trivial Composite Widget
Other Examples

This chapter describes how to write a new GtkWidget. A widget is any GtkObject that derives from GtkWidget; before reading this chapter, you should be familiar with the chapter called The GTK+ Object and Type System. This chapter will discuss the details of GtkWidget, but will not re-explain GtkObject in general. You will also need to know something about GDK to write a widget; be sure to skim the chapter called GDK Basics if you haven't.

Widgets are easy to create; you only need to cut-and-paste the usual GtkObject boilerplate (instance and class initializers, a get_type() function, and so on), and then implement your widget's functionality. Writing new widgets is an important application development technique.

After a brief overview, this chapter jumps straight to the implementation of a very simple widget called GtkEv. Then it takes a step back, describing widget implementation more systematically. It ends with more examples, taken from GTK+ itself. (It pays to become familiar with the GTK+ source code: often the easiest way to implement a widget is to subclass or slightly modify the most similar stock GTK+ widget. Of course, you must comply with the terms of GTK+'s license if you cut-and-paste code from the library.)

Overview

This section gives a brief overview, including the different kinds of widget you might encounter, and the general functionality a GtkWidget is required to have.

Kinds of Widget

The term "widget" is really very broad, since it encompasses any object that implements the GtkWidget interface. There are many ways to classify widgets:

  • Containers are widgets that store other widgets inside, such as the boxes and tables described in the chapter called GTK+ Basics. As the chapter called GTK+ Basics discussed, containers can be subdivided into those that add functionality to a single child (GtkButton, GtkFrame, GtkEventBox, etc.), and those that manage layout for multiple children (GtkBox, GtkTable, etc.). Container widgets are harder to implement than "plain" widgets because the GtkContainer interface must be implemented in addition to the GtkWidget interface.

  • Composite widgets are containers that already contain a useful collection of child widgets in a nice package. For example, the GtkFileSelection widget is a subclass of GtkWindow that already contains a list widget to show files, dialog buttons, and so on. Widgets like this are easy to write, and are a convenient way to code applications. You could write a "MainWindow" widget for your main application window, for example, and then create a new instance of the widget whenever the user opens a new document. GnomeApp and GnomeDialog are two important composite widgets in Gnome.

  • Non-container widgets can be actual controls (buttons, scroll bars, etc.), information displays (GtkLabel), or decorative flourishes (GtkSeparator, for example). As the chapter called GTK+ Basics briefly mentioned, there are two major ways to implement widgets: most widgets (those that need to receive events or draw their own background) have an associated GdkWindow; "no window" widgets draw on their parent container. Widgets without windows are implemented slightly differently. All containers have a GdkWindow (since widgets without one might need to draw on it, among other reasons).

This chapter presents several widgets as examples, including a GtkEv widget written especially for this book, GtkVBox from GTK+, and GnomeAppBar from libgnomeui.

What a Widget Does

A minimal widget implements the following (though GtkWidget's default implementation may be sufficient in many cases):