<!-- ############ chapter ############# -->

<chapter id="chapter-building-args" xreflabel="Adding Properties">
  <title>Adding Properties</title>
  <para>
    The primary and most important way of controlling how an element behaves,
    is through GObject properties. GObject properties are defined in the
    <function>_class_init ()</function> function. The element optionally
    implements a <function>_get_property ()</function> and a
    <function>_set_property ()</function> function. These functions will be
    notified if an application changes or requests the value of a property,
    and can then fill in the value or take action required for that property
    to change value internally.
  </para>
  <para>
    You probably also want to keep an instance variable around
    with the currently configured value of the property that you use in the
    get and set functions. 
    Note that <classname>GObject</classname> will not automatically set your
    instance variable to the default value, you will have to do that in the
    <function>_init ()</function> function of your element.
  </para>
  <programlisting><!-- example-begin properties.c a --><!--
#include "filter.h"
G_DEFINE_TYPE (GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT);
static void
gst_my_filter_class_init (gpointer klass)
{
}
static void
gst_my_filter_init (GstMyFilter * filter)
{
}
--><!-- example-end properties.c a -->
<!-- example-begin properties.c b -->
/* properties */
enum {
  PROP_0,
  PROP_SILENT
  /* FILL ME */
};

static void	gst_my_filter_set_property	(GObject      *object,
						 guint         prop_id,
						 const GValue *value,
						 GParamSpec   *pspec);
static void	gst_my_filter_get_property	(GObject      *object,
						 guint         prop_id,
						 GValue       *value,
						 GParamSpec   *pspec);

static void
gst_my_filter_class_init (GstMyFilterClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  /* define virtual function pointers */
  object_class->set_property = gst_my_filter_set_property;
  object_class->get_property = gst_my_filter_get_property;

  /* define properties */
  g_object_class_install_property (object_class, PROP_SILENT,
    g_param_spec_boolean ("silent", "Silent",
			  "Whether to be very verbose or not",
			  FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_my_filter_set_property (GObject      *object,
			    guint         prop_id,
			    const GValue *value,
			    GParamSpec   *pspec)
{
  GstMyFilter *filter = GST_MY_FILTER (object);

  switch (prop_id) {
    case PROP_SILENT:
      filter->silent = g_value_get_boolean (value);
      g_print ("Silent argument was changed to %s\n",
	       filter->silent ? "true" : "false");
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_my_filter_get_property (GObject    *object,
			    guint       prop_id,
			    GValue     *value,
			    GParamSpec *pspec)
{
  GstMyFilter *filter = GST_MY_FILTER (object);
                                                                                
  switch (prop_id) {
    case PROP_SILENT:
      g_value_set_boolean (value, filter->silent);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}
<!-- example-end properties.c b -->
<!-- example-begin properties.c c --><!--
#include "register.func"
  --><!-- example-end properties.c c --></programlisting>
  <para>
    The above is a very simple example of how properties are used. Graphical
    applications will use these properties and will display a
    user-controllable widget with which these properties can be changed.
    This means that - for the property to be as user-friendly
    as possible - you should be as exact as possible in the definition of the
    property. Not only in defining ranges in between which valid properties
    can be located (for integers, floats, etc.), but also in using very
    descriptive (better yet: internationalized) strings in the definition of
    the property, and if possible using enums and flags instead of integers.
    The GObject documentation describes these in a very complete way, but
    below, we'll give a short example of where this is useful. Note that using
    integers here would probably completely confuse the user, because they
    make no sense in this context. The example is stolen from videotestsrc.
  </para>
  <programlisting>
typedef enum {
  GST_VIDEOTESTSRC_SMPTE,
  GST_VIDEOTESTSRC_SNOW,
  GST_VIDEOTESTSRC_BLACK
} GstVideotestsrcPattern;

[..]

#define GST_TYPE_VIDEOTESTSRC_PATTERN (gst_videotestsrc_pattern_get_type ())
static GType
gst_videotestsrc_pattern_get_type (void)
{
  static GType videotestsrc_pattern_type = 0;

  if (!videotestsrc_pattern_type) {
    static GEnumValue pattern_types[] = {
      { GST_VIDEOTESTSRC_SMPTE, "SMPTE 100% color bars",    "smpte" },
      { GST_VIDEOTESTSRC_SNOW,  "Random (television snow)", "snow"  },
      { GST_VIDEOTESTSRC_BLACK, "0% Black",                 "black" },
      { 0, NULL, NULL },
    };

    videotestsrc_pattern_type =
	g_enum_register_static ("GstVideotestsrcPattern",
				pattern_types);
  }

  return videotestsrc_pattern_type;
}

[..]

static void
gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
{
[..]
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATTERN,
    g_param_spec_enum ("pattern", "Pattern",
		       "Type of test pattern to generate",
                       GST_TYPE_VIDEOTESTSRC_PATTERN, GST_VIDEOTESTSRC_SMPTE,
                       G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
[..]
}
  </programlisting>
</chapter>
