GtkSharp/gconf/doc/intro.html
Rachel Hestilow d33dd8a15f 2002-10-19 Rachel Hestilow <hestilow@ximian.com>
* gconf, sample/gconf: Added.

	* glue/combo.c: This was never added, add it now.

	* configure.in, makefile, sample/Makefile.in: Build new
	gconf bindings if gnome is enabled.

svn path=/trunk/gtk-sharp/; revision=8389
2002-10-19 09:31:20 +00:00

208 lines
9.6 KiB
HTML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Using GConf#</title>
</head>
<body>
<p align="center">
<font size="+3">Using GConf#</font></p>
<h1>Introduction</h1>
<p>Using GConf directly from an application is often inconvenient.
Because the configuration key system effectively represents a
string-based API, accessing GConf values leaves your application
open to runtime errors from a single typo. Even if you store your
keys in constants (as is recommended), you still wind up maintaining
two lists of keys: one in the schema, and one in your app.</p>
<p>Another problem is that the GConf value types are very limited:
string, float, int, bool, and list. When storing common value types
such as colors or enumerations, one has to serialize these values
to and from strings.</p>
<p>Finally, providing graphical dialogs for your settings can be a very
tedious process. For each config element exposed in your UI, you have
to manually hook up the "changed" signal on the UI to a custom handler
setting the GConf value. Inversely, one must initially populate the
dialog based on previously-set GConf values. Complicating all of this
is the GNOME HIG, which specifies that all preference dialogs be
instant-apply if possible.</p>
<p>GConf# addresses these issues with two new utilities: SchemaGen, and
the GConf.PropertyEditors library.</p>
<h1>SchemaGen</h1>
<p>SchemaGen is a new tool which generates a custom API for the settings
in a gconf schema file. Given a schema, it generates two classes,
<b>Settings</b> and <b>SettingKeys</b>. <b>Settings</b> provides static
properties for each specified gconf setting. These properties map
directly to the values in the gconf database. <b>Settings</b> also
specifies static events for each setting indicating when the setting
has changed, and a generic Changed event which notifies when any
of your settings have changed. Finally, for every property in
<b>Settings</b>, SchemaGen creates a read-only property of the same
name in <b>SettingKeys</b> specifying the GConf key used to access
this property. <b>SettingKeys</b> is not needed if you are only using
the <b>Settings</b> class, but it is very useful when attaching
PropertyEditors, or when accessing GConf directly.</p>
<p>SchemaGen also provides for limited marshalling to and from the
GConf value types. It currently defines marshallers for
System.Drawing.Color and for enumerations. This is done by specifying
a <b>cstype</b> directive in the GConf schema.</p>
<h2>Example</h2>
<p>First, we need to write a GConf schema specifying our settings.</p>
<pre>
&lt;gconfschema&gt;
&lt;schemalist&gt;
&lt;schema&gt;
&lt;key&gt;/schemas/apps/gconfsharp/sample_app/toolbar_alignment&lt;/key&gt;
&lt;applyto&gt;/apps/gconfsharp/sample_app/toolbar_alignment&lt;/applyto&gt;
&lt;owner&gt;sample_app&lt;/owner&gt;
<b> &lt;type&gt;string&lt;/type&gt;</b>
<b> &lt;cstype class="Sample.Alignment"&gt;enum&lt;/cstype&gt;</b>
&lt;locale name="C"&gt;
&lt;short&gt;Toolbar alignment&lt;/short&gt;
&lt;long&gt;Where the toolbar should be. Can be one of Top, Bottom, Left, Rigt.&lt;/long&gt;
&lt;/locale&gt;
&lt;default&gt;Top&lt;/default&gt;
&lt;/schema&gt;
&lt;schema&gt;
&lt;key&gt;/schemas/apps/gconfsharp/sample_app/text_color&lt;/key&gt;
&lt;applyto&gt;/apps/gconfsharp/sample_app/text_color&lt;/applyto&gt;
&lt;owner&gt;sample_app&lt;/owner&gt;
<b> &lt;type&gt;string&lt;/type&gt;</b>
<b> &lt;cstype&gt;color&lt;/cstype&gt;</b>
&lt;locale name="C"&gt;
&lt;short&gt;Text color&lt;/short&gt;
&lt;long&gt;Text color&lt;/long&gt;
&lt;/locale&gt;
&lt;default&gt;#000000&lt;/default&gt;
&lt;/schema&gt;
&lt;schema&gt;
&lt;key&gt;/schemas/apps/gconfsharp/sample_app/enable_text_color&lt;/key&gt;
&lt;applyto&gt;/apps/gconfsharp/sample_app/enable_text_color&lt;/applyto&gt;
&lt;owner&gt;sample_app&lt;/owner&gt;
&lt;type&gt;bool&lt;/type&gt;
&lt;locale name="C"&gt;
&lt;short&gt;Show colored text&lt;/short&gt;
&lt;long&gt;Show colored text&lt;/long&gt;
&lt;/locale&gt;
&lt;default&gt;#000000&lt;/default&gt;
&lt;/schema&gt;
&lt;/schemalist&gt;
&lt;/gconfschemafile&gt;
</pre>
<p>Note how we specify both the cstype and type for the enum and color.
This is because GConf doesn't know anything about cstype.</p>
<p>We save this to sample.schema, and install it with the command:</p>
<pre>env GCONF_CONFIG_SOURCE="" gconftool-2 --makefile-install-rule sample.schema</pre>
<p>GConf generates a warning because it doesn't recognize cstype, but
it is nothing to worry about.</p>
<p>We're now ready to run SchemaGen. Installing the schema before running
SchemaGen is not required, but you should make sure to install it before
running your application, because GConf# will throw an exception if
GConf can't find your settings.</p>
<p>SchemaGen's full executable name is <b>gconfsharp-schemagen</b>. It
takes a namespace and the schema filename as parameters, and outputs
to the console. Here is the command used to generate Settings.cs for
sample.schema:</p>
<pre>gconfsharp-schemagen Sample sample.schema &gt; Settings.cs</pre>
<p>Now we're ready to write a small program using our new settings.</p>
<pre>
namespace Sample
{
using System;
using System.Drawing;
public enum Alignment
{
Top,
Bottom,
Left,
Right
}
class X
{
public static void Main (string args[])
{
Alignment align = Settings.ToolbarAlignment;
Console.WriteLine ("Alignment is: {0}", align);
Settings.ToolbarAlignment = Left;
Console.WriteLine ("Color is: {0}", Settings.TextColor);
Console.WriteLine ("Color is enabled: {0}", Settings.TextEnableColor);
}
}
}
</pre>
<p>As you can see, our GConf settings are now nicely encapsulated, and
are as easy to access as any other .NET properties.</p>
<h1>Property Editors</h1>
<p>Property Editors are objects which act as intermediaries between
GConf and Gtk+ widgets. They are analoguous to the Controller of the MVC
design pattern. Property editors do two things:
<ul>
<li>They listen to GConf notifications, and update the widget
to reflect any changes in a GConf setting.
<li>They connect to the various "changed" signals on a widget,
and update GConf to reflect the widget's current state.</li>
</ul>
This means that the widget and GConf are always in sync, no matter
if the value is set through Gtk+ or through GConf. GConf# defines a
number of Property Editors which correspond to common widget/setting
combinations -- for example, a CheckButton representing a boolean
setting.
</p>
<p>GConf# also provides a utility class called <b>EditorShell</b>.
EditorShell exposes a simple API to automatically construct
PropertyEditors for a Glade UI.</p>
<p>As a historical note, and in the interests of giving credit where
credit is due, it should be noted that GConf Property Editors are
not unique to GConf#. They were originally conceived and implemented
by Bradford Hovinen for use in the GNOME Control Center. Although
the APIs are somewhat similar, the original version was written in
C and was limited to internal use in the Control Center.</p>
<h2>Example</h2>
<p>For this example we'll assume you have written a Glade UI for
the settings in the previous example. It employs three elements:
an option menu named "toolbar_menu", a checkbox named "enable_check",
and a color picker named "colorpicker". Given our Glade.XML object,
all we have to do is set up the EditorShell.</p>
<pre>
Glade.XML gxml = <i>...</i>
GConf.PropertyEditors.EditorShell shell = new GConf.PropertyEditors.EditorShell (gxml);
shell.Add (SettingKeys.ToolbarAlignment, "toolbar_menu", typeof (Sample.Alignment));
shell.Add (SettingKeys.EnableTextColor, "enable_check");
shell.Add (SettingKeys.TextColor, "colorpicker");
</pre>
<p>That's all that is needed to implement the preferences dialog. Note
how we didn't have to specify what type of property editor to use.
The EditorShell uses introspection to create the correct Property
Editor for all the types of widgets it knows about. Also note that
because ToolbarAlignment is an enum, we had to pass its type in so that
the Property Editor can store its value correctly. By default,
Property Editors assume that the order of elements in an OptionMenu
(or RadioButton) correspond to the order of values in an enum. If
this is not the case, you can pass in an additional parameter to
Add: an array of integers, each array element being the integer
representation of an enum value. This array represents the order of
values in your GUI element.
</p>
<p>Now, a really good preference dialog would "ghost out" the
color picker if the "Enable text color" option is disabled. This
requires a small addition to our previous code:</p>
<pre>
shell.AddGuard (SettingKeys.EnableTextColor, "color_box");
</pre>
<p>Again, for the purposes of the example, "color_box" is the name of the
HBox containing the label and color picker corresponding to TextColor.</p>
<h1></h1>
<p>
<font size=-1>
<i>Last updated: October 19th, 2002 <br />
Rachel Hestilow <a href="mailto:hestilow@ximian.com">(hestilow@ximian.com)</a></i>
</font>
</p>
</body>
</html>