fix up id's
[platform/upstream/gstreamer.git] / docs / pwg / building-props.xml
1 <!-- ############ chapter ############# -->
2
3 <chapter id="chapter-building-args" xreflabel="Adding Arguments">
4   <title>Adding Arguments</title>
5   <para>
6     The primary and most important way of controlling how an element behaves,
7     is through GObject properties. GObject properties are defined in the
8     <function>_class_init ()</function> function. The element optionally
9     implements a <function>_get_property ()</function> and a
10     <function>_set_property ()</function> function. These functions will be
11     notified if an application changes or requests the value of a property,
12     and can then fill in the value or take action required for that property
13     to change value internally.
14   </para>
15   <programlisting>
16 /* properties */
17 enum {
18   ARG_0,
19   ARG_SILENT
20   /* FILL ME */
21 };
22
23 static void     gst_my_filter_set_property      (GObject      *object,
24                                                  guint         prop_id,
25                                                  const GValue *value,
26                                                  GParamSpec   *pspec);
27 static void     gst_my_filter_get_property      (GObject      *object,
28                                                  guint         prop_id,
29                                                  GValue       *value,
30                                                  GParamSpec   *pspec);
31
32 static void
33 gst_my_filter_class_init (GstMyFilterClass *klass)
34 {
35   GObjectClass *object_class = G_OBJECT_CLASS (klass);
36
37   /* define properties */
38   g_object_class_install_property (object_class, ARG_SILENT,
39     g_param_spec_boolean ("silent", "Silent",
40                           "Whether to be very verbose or not",
41                           FALSE, G_PARAM_READWRITE));
42
43   /* define virtual function pointers */
44   object_class->set_property = gst_my_filter_set_property;
45   object_class->get_property = gst_my_filter_get_property;
46 }
47
48 static void
49 gst_my_filter_set_property (GObject      *object,
50                             guint         prop_id,
51                             const GValue *value,
52                             GParamSpec   *pspec)
53 {
54   GstMyFilter *filter = GST_MY_FILTER (object);
55
56   switch (prop_id) {
57     case ARG_SILENT:
58       filter->silent = g_value_get_boolean (value);
59       g_print ("Silent argument was changed to %s\n",
60                filter->silent ? "true" : "false");
61       break;
62     default:
63       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
64       break;
65   }
66 }
67
68 static void
69 gst_my_filter_get_property (GObject    *object,
70                             guint       prop_id,
71                             GValue     *value,
72                             GParamSpec *pspec)
73 {
74   GstMyFilter *filter = GST_MY_FILTER (object);
75                                                                                 
76   switch (prop_id) {
77     case ARG_SILENT:
78       g_value_set_boolean (value, filter->silent);
79       break;
80     default:
81       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
82       break;
83   }
84 }
85   </programlisting>
86   <para>
87     The above is a very simple example of how arguments are used. Graphical
88     applications - for example GStreamer Editor - will use these properties
89     and will display a user-controlleable widget with which these properties
90     can be changed. This means that - for the property to be as user-friendly
91     as possible - you should be as exact as possible in the definition of the
92     property. Not only in defining ranges in between which valid properties
93     can be located (for integers, floats, etc.), but also in using very
94     descriptive (better yet: internationalized) strings in the definition of
95     the property, and if possible using enums and flags instead of integers.
96     The GObject documentation describes these in a very complete way, but
97     below, we'll give a short example of where this is useful. Note that using
98     integers here would probably completely confuse the user, because they
99     make no sense in this context. The example is stolen from videotestsrc.
100   </para>
101   <programlisting>
102 typedef enum {
103   GST_VIDEOTESTSRC_SMPTE,
104   GST_VIDEOTESTSRC_SNOW,
105   GST_VIDEOTESTSRC_BLACK
106 } GstVideotestsrcPattern;
107
108 [..]
109
110 #define GST_TYPE_VIDEOTESTSRC_PATTERN (gst_videotestsrc_pattern_get_type ())
111 static GType
112 gst_videotestsrc_pattern_get_type (void)
113 {
114   static GType videotestsrc_pattern_type = 0;
115
116   if (!videotestsrc_pattern_type) {
117     static GEnumValue pattern_types[] = {
118       { GST_VIDEOTESTSRC_SMPTE, "smpte", "SMPTE 100% color bars" },
119       { GST_VIDEOTESTSRC_SNOW,  "snow",  "Random (television snow)" },
120       { GST_VIDEOTESTSRC_BLACK, "black", "0% Black" },
121       { 0, NULL, NULL },
122     };
123
124     videotestsrc_pattern_type =
125         g_enum_register_static ("GstVideotestsrcPattern",
126                                 pattern_types);
127   }
128
129   return videotestsrc_pattern_type;
130 }
131
132 [..]
133
134 static void
135 gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
136 {
137 [..]
138   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE,
139     g_param_spec_enum ("pattern", "Pattern",
140                        "Type of test pattern to generate",
141                        GST_TYPE_VIDEOTESTSRC_PATTERN, 1, G_PARAM_READWRITE));
142 [..]
143 }
144   </programlisting>
145 </chapter>