This document describes how to add widgets to Gazpacho
------------------------------------------------------

The widgets available in Gazpacho are handled through widget catalogs.
A catalog is a list of widgets and information about them. Gazpacho is
shipped with a catalog for GTK+ widgets.

The catalog file is written in an XML format that will be described
below. There is also a DTD for the format which can be found in the
catalogs directory.

Many aspects of a widget can be handled automatically by the GObject
introspection features. Not all of them can though, and advanced widgets
often need additional support from code. This is specified in the
catalog file, where you can override default values, hide properties,
specify functions to should be used to override behavior etc. Several
examples of this can be found in the GTK+ catalog file and the
gladegtk.py source code, where many GTK+ widgets have supporting code.

The catalog file is also used to group the widgets in groups that
correspond to the groups in the Gazpacho widget palette. You can also
specify which property page, Common or Widget, each property should be
displayed on.


The catalog file
----------------

Let's take a look at the gtk+.xml catalog file. It starts by specifying
the name of the catalog and the library to use:

<glade-catalog name="gtk+" library="gladegtk">
  <glade-widget-classes>

    ... widgets go here


The library consists of the Python code for the supporting functions
needed by the widgets in the catalog. See gazpacho/gladegtk.py for
examples of such code.


Widgets
-------

Each widget is listed in the catalog, a simple example is GtkLabel:

    <glade-widget-class name="GtkLabel" generic-name="label" title="Label">
       ...
    </glade-widget-class>

The name is the GObject class name of the widget. Generic name is used
to get the icon name for the widget palette, and is a regular icon theme
icon. The generic name is also used to generate a default name for
instances of the widget in the UI editor.


Properties
----------

Let's expand the example from above:

    <glade-widget-class name="GtkLabel" generic-name="label" title="Label">
      <properties>
	<property id="label" default="label"/>
	<property id="pattern" default=""/>
      </properties>
    </glade-widget-class>

The default values of two properties, label and pattern, have been
overridden.

You can also mark a property as optional, in which case there is a
checkbutton displayed next to it in the editor and the property will
only be set if the checkbutton is enabled:

	<property id="my-property" optional="True" optional-default="False" default="my-value"/>

The "optional-default" parameter specifies if the checkbutton should be
checked or not by default. An example of "optional" is used is the
default width and height of a window where you sometimes don't want to
set a value.

Normally, the tooltip for a property is retrieved through GObject
introspection but if for some reason the value is not usable, it can be
overridden:

	<property id="label" default="label"/>
          <tooltip>A tooltip for this property</tooltip>
	</property>

Using the "common" parameter, a property can be placed on the Common
property editor page instead of the widget page:

        <property common="True" id="visible"/>

Properties that don't have the common parameter are placed on the Widget
page. Packing properties are always placed on the Packing page.

Some properties does not make much sense for certain widgets. An example
of this can be seen in the GtkTreeView widget, which is a subclass of
GtkContainer, but as an internal implementation detail and not for
putting child widgets in. Therefore the "resize-mode" property of
GtkContainer is disabled for the tree view:

        <property id="resize-mode" disabled="TRUE"/>

For cases where a property should be hidden for a lot of widgets, there
is a function, visibility-function that can be implemented instead:

        <property id="tooltip" name="tooltip">
          <visibility-function>glade_gtk_widget_condition</visibility-function>
        </property>

The function can then return True or False depending on which class the
widget is.


Internationalization
--------------------

String properties are by default treated as translatable strings. This
means that the user can edit extra metadata in the Gazpacho UI. For some
strings this does not make sense, and those can be marked as
non-translatable:

        <property id="role" translatable="False"/>


Fake properties
---------------

For some widgets it makes sense to add a "fake" property. This is used
for instance for the box and table containers where properties have been
added for the size and number of rows and columns. Otherwise there would
be no easy way to change that in the editor. In such cases the property
needs to be handled completely in the support code:

	<property ...>
	  <spec>my_param_spec</spec>
	  <set-function>my_widget_set_my_property</set-function>
	  <get-function>my_widget_get_my_property</get-function>
	</property>

The spec function is used to get the GParamSpec for the property type.
Set and get should be self-explanatory, as they are used to set and get
the value of the property.


Custom property editor widgets
------------------------------

In some cases, a simple number or string entry is not enough to make a
usable interface for editing a property. Examples of this are a stock
icon chooser and a list of flags to choose from.

To use a custom editor for a property, two functions are needed:

	<property ...>
          <editor>
            <create-function></create-function>
            <load-function></load-function>
          </editor>
	</property>

The create-function creates the editor widget and returns it, while the
load-function sets the value in the widget.


Container widgets
-----------------

Most container widgets need support code to be usable in Gazpacho. When
first created, one or more placeholders need to be inserted into the
container. For containers with a fixed number of children, like a GtkBin
(1) or GtkPaned (2), the fill-empty function should be used.

For other containers, such as a GtkBox, there is often one or more fake
properties that specify the number of children. The initial creating of
placeholders for each child can then be handled by setting default
values and letting the set-function for the fake properties handle the
rest. An example of this is GtkBox, where the fake property size is set
to 3 by default. When the set-function is run, it creates and inserts
three placeholders into the box.

When replacing a placeholder with a real child widget, or when deleting
a widget (and in effect replacing it with a placeholder child), the
replace-child-function is used.


Querying the user (NOTE: this is not implemented)
-----------------

Some properties might make sense to query the user for before creating a
widget. This is used for instance for the size of boxes and number of
buttons in a dialog. To achieve this, simply set the query parameter of
the property:

	<property id="my-property">
	  <query>
            <question>The question to ask for this property</question>
          </query>
	</property>


Property parameters
-------------------

Properties can have additional parameters that affect their behavior in
the editor. For numeric properties this lets you set the behavior of the
spinbutton used to enter the value. Example:

	<property id="n-rows" default="3" query="True">
	  <parameters>
	    <parameter key="Min" value="1"/>
	    <parameter key="Max" value="10000"/>
	    <parameter key="StepIncrement" value="1"/>
	    <parameter key="PageIncrement" value="10"/>
	    <parameter key="ClimbRate" value="1"/>
	  </parameters>
	</property>

For string values, the parameter "visible-lines" specify whether to use
a single line entry or a multiple line text view to edit the text.


Packing defaults
----------------

To make using Gazpacho easier, the default packing properties can be
set. This makes it possible to specify how to pack a widget in certain
containers. An example is the menu bar, which shouldn't expand if put
inside a vbox:

    <glade-widget-class name="GtkMenuBar" generic-name="menubar" title="Menu Bar">
      <packing-defaults>
        <parent-class name="GtkVBox">
         <child-property id="expand" default="false"/>
       </parent-class>
      </packing-defaults>
    </glade-widget-class>

The parent class is the class of the container, and there can be one or
more listed. For each parent class, the default values are specified.


Grouping
--------

The widgets are grouped in different sections in the Gazpacho UI. Those
groups are defined in the catalog file as follows:

 <glade-widget-group name="my-widgets" title="My widgets">
    <glade-widget-class-ref name="MyFirstWidget"/>
    <glade-widget-class-ref name="MysecondWidget"/>

    ...
 </glade-widget-group>


The file should contain one or more widget groups.


Summary of functions
--------------------

The functions available when implementing widget support code are listed
here. First the functions that apply to the property tag:

set_function(widget, value)
get_function(widget, value)

  Set and get the value of a property.

  widget is a GtkWidget subclass
  value is a GValue

spec_function()

  The param spec to use for the property.

  The return value is a GParamSpec

visibility_function (widget_class)

  Specify if the property is visible or not for the specified class.

  widget_class is a gazpacho.WidgetClass
  The return value is a boolean

create_function()

  Create a custom editor widget for the property.

  The return value is a GtkWidget.

load_function(editor, widget, proxy)

  This function is called to load a widget into a special editor (created in
  create_function()). The widget is the corresponding GtkWidget that the
  editor can read current values from.

  The proxy object is used to set values on the widget since it needs to be
  handled through Gazpachos framework for this (to work with undo/redo and 
  saving). 

  The proxy object has two functions, set_value and set_property. In most 
  cases set_value is what you want. That is if your editor only operates 
  on the property it's attached to. If instead you need to set other 
  properties on widget, as an example in GtkImage there is a manually added
  property called 'icon', but when changing that in the editor it actually
  sets the properties 'file' and 'stock'. It's then using the function 
  set_property which also takes a property id as first argument.

Properties that apply to container widgets:

replace_child_function(current, new, container)

  Replace a placeholder with a widget, or vice versa.

  current is the current child, either a GtkWidget or a Placeholder
  new is the new child, GtkWidget or Placeholder
  container is a GtkWidget

fill_empty_function(widget)

  Setup initial placeholders after creating the container.

  widget is the container to fill

get_internal_child_function(widget, name)

  This is currently not used.

child_property_applies_function(ancestor, widget, property_id)

  Used to decide if the property applies to a widget, which is an
  internal child of ancestor. See GtkDialog for an example.

  ancestor is a GtkWidget
  widget is a GtkWidget
  property_id is a string with the name of the property

  The return value is a boolean.


Properties that apply to any widgets:

post_create_function(widget)

  Called after creating a widget. This is usually used to do some setup,
  like setting a default size.

  widget is a GtkWidget.

pre_create_function(widget)

  Note: This is called right before post_create and isn't really used.


Validating the catalog file
---------------------------

The DTD that is shipped with Gazpacho can be used to validate your catalog
file. Note that properties must be entered in the same order as they are
specified in the DTD for the validation to pass.

To validate a fil, do this:

 xmllint --dtdvalid glade-catalog.dtd --noout my-catalog.xml





