Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Gtk+/Gnome Application Development
Prev Home Next

Using Object Arguments in YourOwn GtkObject Subclass

If you're writing a custom GtkObject or a custom subclass of some existing object, you can register your own object arguments in the class initialization function, at the same time you register your object's signals. To do this, call gtk_object_add_arg_type()---here's an example from GtkContainer:


    gtk_object_add_arg_type("GtkContainer::border_width", 
                            GTK_TYPE_ULONG, 
                            GTK_ARG_READWRITE, 
                            ARG_BORDER_WIDTH);
  

The first argument must be a static string constant, because GTK+ does not copy it. It must also begin with the name of your new class, separated from the name of the argument by two colons (reminiscent of the C++ scope operator). The second argument should be the type of the argument; this can be any GtkType GTK+ knows about.

The third argument contains one or more flags, defined in gtk/gtkobject.h. The available flags are:

  • GTK_ARG_READABLE means the argument's value can be read, using gtk_object_getv().

  • GTK_ARG_WRITABLE means the argument's value can be written, using gtk_object_set() or gtk_object_setv()

  • GTK_ARG_CONSTRUCT means the argument should be initialized with a default value. This applies to numeric and pointer types; they are set to 0 or NULL, respectively. (This happens within gtk_object_new() or gtk_widget_new(), which call gtk_object_default_construct().)

  • GTK_ARG_CONSTRUCT_ONLY means the argument is only used for object construction; it cannot be read or written later. That is, you can't use these arguments with gtk_object_set().

  • GTK_ARG_CHILD_ARG is used by subclasses of GtkContainer; GtkContainer implements a specialized variation on the argument system to permit setting the attributes of child-container pairs (such as packing flags for GtkBox---the flags are not a property of the child or the container, but of the pair). You will only use this flag if you're writing a new type of container, or some other kind of object with similar semantics.

  • GTK_ARG_READWRITE is shorthand for (GTK_ARG_READABLE | GTK_ARG_WRITABLE).

There are some limitations on which flags can be used.

  • All arguments must be either readable or writable.

  • GTK_ARG_CONSTRUCT arguments must be both readable and writable.

  • GTK_ARG_CONSTRUCT_ONLY arguments must be writable.

  • GTK_ARG_CHILD_ARG should not be used outside of container-style object implementations; it is used internally by the GtkContainer child argument functions.

The fourth and final argument to gtk_object_add_arg_type() is an argument ID to be used by the object subclass to identify this argument. This can be any integer except 0, but it is customary to use a private enumeration in the object implementation's .c file. GtkObject has two class functions any subclass with arguments must implement: one to get arguments specific to the subclass, and one to set them. These functions are passed the argument ID, so they know which argument to get or set. Argument IDs reduce the need for string comparisons, increasing the efficiency of argument manipulation.

For example, GtkContainer defines these functions:

 
static void gtk_container_get_arg(GtkObject* object,
                                  GtkArg* arg,
                                  guint arg_id);
static void gtk_container_set_arg(GtkObject* object,
                                  GtkArg* arg,
                                  guint arg_id);

It uses this enumeration to create its argument IDs:


enum {
  ARG_0,              /* Skip 0, an invalid argument ID */
  ARG_BORDER_WIDTH,
  ARG_RESIZE_MODE,
  ARG_CHILD
};

It registers its arguments in gtk_container_class_init() as follows:


  gtk_object_add_arg_type("GtkContainer::border_width",
                          GTK_TYPE_ULONG, 
                          GTK_ARG_READWRITE, 
                          ARG_BORDER_WIDTH);
  gtk_object_add_arg_type("GtkContainer::resize_mode", 
                          GTK_TYPE_RESIZE_MODE, 
                          GTK_ARG_READWRITE, 
                          ARG_RESIZE_MODE);
  gtk_object_add_arg_type("GtkContainer::child", 
                          GTK_TYPE_WIDGET, 
                          GTK_ARG_WRITABLE, 
                          ARG_CHILD);

gtk_container_set_arg() and gtk_container_get_arg() are installed in the class struct:


  object_class->get_arg = gtk_container_get_arg;
  object_class->set_arg = gtk_container_set_arg;

gtk_container_set_arg() and gtk_container_get_arg() are then implemented like this:


static void
gtk_container_set_arg (GtkObject    *object,
                       GtkArg       *arg,
                       guint         arg_id)
{
  GtkContainer *container;

  container = GTK_CONTAINER (object);

  switch (arg_id)
    {
    case ARG_BORDER_WIDTH:
      gtk_container_set_border_width (container, GTK_VALUE_ULONG (*arg));
      break;
    case ARG_RESIZE_MODE:
      gtk_container_set_resize_mode (container, GTK_VALUE_ENUM (*arg));
      break;
    case ARG_CHILD:
      gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg)));
      break;
    default:
      break;
    }
}

static void
gtk_container_get_arg (GtkObject    *object,
                       GtkArg       *arg,
                       guint         arg_id)
{
  GtkContainer *container;

  container = GTK_CONTAINER (object);
  
  switch (arg_id)
    {
    case ARG_BORDER_WIDTH:
      GTK_VALUE_ULONG (*arg) = container->border_width;
      break;
    case ARG_RESIZE_MODE:
      GTK_VALUE_ENUM (*arg) = container->resize_mode;
      break;
    default:
      arg->type = GTK_TYPE_INVALID;
      break;
    }
}    

Notice that the type must be set to GTK_TYPE_INVALID if your subclass doesn't understand the argument ID. This is used as an error indicator; users who call gtk_object_getv() will check for it.

If you flip back to page XXXX and have another look at the GtkButton class initialization function, you should now understand what is going on with respect to object arguments.

Gtk+/Gnome Application Development
Prev Home Next

 
 
  Published under free license. Design by Interspire