Four complete examples are presented that demonstrate several
different techniques for using UIL with python.

- The "Simple Button using AddCallback" example shows how to use UIL
  to build a widget hierarchy but use the python AddCallback method to
  add callbacks to the UIL-created widgets.

- The "Simple Button using PyEval" example shows how to use the
  Mrm-registered function PyEval() in place of the python AddCallback
  method to add callbacks to widgets directly from UIL.  This
  illustrates a powerful feature of the Mrm binding -- the ability to
  connect to predefined python functions without writing any code.

- The "Simple Button using PyRegister" example shows the use of
  PyRegister to declare a Python function to be a Mrm-registered
  callback function.  This capability is useful for prototyping in UIL
  where the prototype will eventually be ported -- the callbacks are
  migrated from python code to C or C++, but the UIL remains the same.

- The "Command Line Program Front End" example shows the use of the
  MrmNcreateCallback and the __widget__ symbol to enter the python
  widget objects for widgets created in UIL into a python symbol
  dictionary.


Simple Button using AddCallback
-------------------------------

This example demonstrates about the simplest possible example of using
the Mrm module.  There are three files required -- a .uil file named
button.uil, a .uid file named button.uid, and a python script named
testbutton.py.

button.uil is compiled to button.uid by the statement:

	uil button.uil -o button.uid

The script is executed by the statement:

	python testbutton.py

When executed, the testbutton.py script first declares the function
OnActivate().  OnActivate is a typical callback function, called with
widget, client data and call data arguments.  It prints its widget and
client data argument.  The call data argument is binary, hence ugly
when printed.

Then the script declares the function main().  main() opens the
hierarchy defined by button.uid, fetches the widget named "main",
which is a bulletin board, and its child, a pushbutton.  Next, main()
uses NameToWidget to obtain a python widget object for the button
widget, and adds OnActivate() as the XmNactivateCallback function,
passing "Hi" as the client data.  main() then manages these widgets,
realizes the shell, and enters the Xt Event Loop.

Finally, the script invokes main(), which executes the function
main(), and generates the interface as described above.

When the user pushes the pushbutton (labelled "Push Me" by the
XmNlabelString resource specified in the .uil file), the OnActivate()
function is called with the string "Hi" as its client data.
OnActivate prints "Hi" on stdout.

Simple Button using PyEval
--------------------------

This example demonstrates the use of PyEval() in UIL to evaluate a
string that invokes a callback.  If the callback were "pre-defined",
then a UIL-writer would not have to write any python code to use this
technique, other than the string passed to PyEval() to evaluate.

There are three files required -- a .uil file named button2.uil, a
.uid file named button2.uid, and a python script named testbutton2.py.


button2.uid is created by the uil compiler as noted in the first
example.

The script is executed by the statement:

	python testbutton2.py

When executed, the testbutton2.py script first declares the function
MyPrint().  MyPrint() is in the scope of the python "unnamed" module
__main__ because no other module was named for MyPrint() to be in the
scope of.  This is an important point, because PyEval evaluates its
string in this namespace, and so can find MyPrint().

Then the script declares the function main().  main() declares the
global g_var.  g_var is also in the __main__ namespace, for the same
reason as MyPrint().  g_var is defined in this namespace so that it
can be used in the tag argument of the PyEval call.  The script opens
the hierarchy defined by button.uid, fetches the widget named "main",
which is a bulletin board, and its child, a pushbutton, manages these
widgets and realizes the shell, and enters the Xt Event Loop.

Finally, the script invokes the main() function, which executes the
code and builds the interface.

When the user pushes the pushbutton (labelled "Push Me" in the .uil
file), the PyEval() function is called with the string
"MyPrint(g_var)".  This string is evaluated by python in the context
of module __main__, and calls MyPrint() passing as the argument the
variable g_var.  MyPrint() simply prints it's argument's value, which
is that of g_var -- "a global value".

Note that if the testbutton2.py script was imported, then MyPrint()
would not be in __main__ namespace.  testbutton2.py could be imported
by the statement:

	import testbutton2

In this case, MyPrint and g_var would be globals in the module
testbutton2's namespace; and so the .uil file would have to be coded
differently to invoke MyPrint(), as shown below:

	callbacks {
	    activateCallback = procedure PyEval(
		"import testbutton2; testbutton2.MyPrint(testbutton2.g_var)");
	};

Simple Button Using PyRegister
------------------------------

This example demonstrates the use of PyRegister() in UIL to register a
python function as an Mrm callback.

There are three files required -- a .uil file named reg.uil, a .uid
file named reg.uid, and a python script named testreg.py.

reg.uid is created by the uil compiler as noted in the first example.

The script is executed by the statement:

	python testreg.py

When executed, the testreg.py script first declares the function
MyPrint().  MyPrint is a typical python callback function, and has
widget, clientdata, and calldata arguments.  MyPrint simply prints its
widget and clientdata arguments.

Then the script declares the function main().  main opens the
hierarchy defined by button.uid.  main() then uses PyRegister() to
register MyPrint as an Mrm callback function, with a client argument
of type widget.  Note that this must be done before the FetchWidget
call, so that MyPrint() is registered before being used in the UIL.
main() then fetches the widget named "main", which is a bulletin
board, and its child, a pushbutton, manages these widgets and realizes
the shell, and enters the Xt Event Loop.

Finally, the script invokes the main() function, which executes the
code and builds the interface.

When the user pushes the pushbutton (labelled "Push Me" in the .uil
file), the MyPrint() function is called.  The widget argument is the
pushbutton widget wrapped as a python widget object; the client
argument is the bulletin board widget main wrapped as a python widget
object; and the call argument is the call data structure appropriate
to an XmNactivateCallback wrapped as a python string object.
MyPrint() prints the widget and call arguments.

Because MyPrint was declared to have a client data argument of type
widget, when MyPrint is called the client argument is wrapped as a
python widget argument.  The argument could also have been declared to
be of type integer or string, in which case it would have be wrapped
as the appropriate python object.  The declaration of the argument
type of MyPrint() in the PyRegister function should match that
declared in UIL.

Command Line Program Front End
------------------------------

This example is a simple front end to the unix "cp" command that
demonstrates the use of the MrmNcreateCallback to enter the widgets
created by UIL into module __main__'s dictionary.  This is somewhat
cleaner than having to find the UIL-created widgets using
NameToWidget.  The files involved are panel_cp.uil, panel_cp.uid and
panel_cp.py.

panel_cp.uil is compiled to panel_cp.uid by the statement:

	uil panel_cp.uil -o panel_cp.uid

This example demonstrates using the OnCreate MrmNcreateCallback to
access the __widget__ symbol and insert an entry in the __main__
module's dictionary for the XmText and XmPushButton widgets declared
in the UIL.  This makes these widgets accessable as python-wrapped
widget objects to the OnValueChanged and OnCopy callback routines,
without having to pass the widgets to these callbacks in the UIL tag
argument.

Another way to accomplish this is to insert the names into the
__main__ namespace explicitly in main(), for example:

	global src_file_w, dst_file_w

	...
	main_w = mrm_hier.FetchWidget("main", top_level)
	src_file_w = main_w.NameToWidget('src_file')
	dst_file_w = main_w.NameToWidget('dst_file')

Here, 'src_file' and 'dst_file' are the widget's names as specified in
the UIL, and (Xt)NameToWidget is used to find the widgets, obtain
python wrapped widget objects, and initialize src_file_w and
dst_file_w global variables.
