[rkward-cvs] rkward/doc/en writing_plugins_introduction.docbook,1.3,1.4

Thomas Friedrichsmeier tfry at users.sourceforge.net
Wed Mar 22 21:11:56 UTC 2006


Update of /cvsroot/rkward/rkward/doc/en
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15160

Modified Files:
	writing_plugins_introduction.docbook 
Log Message:
More documentation progress

Index: writing_plugins_introduction.docbook
===================================================================
RCS file: /cvsroot/rkward/rkward/doc/en/writing_plugins_introduction.docbook,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** writing_plugins_introduction.docbook	22 Mar 2006 17:27:55 -0000	1.3
--- writing_plugins_introduction.docbook	22 Mar 2006 21:11:53 -0000	1.4
***************
*** 27,30 ****
--- 27,31 ----
  </affiliation>
  </author>
+ <!-- Additional authors go here -->
  </authorgroup>
  
***************
*** 349,353 ****
  </programlisting>
  <para>
! Inside the <frame> we place another <checkbox> (using checked="true", we signal that checkbox should be checked by default), and a <spinbox>. The spinbox allows the user to select a value between "min" and "max" with the default/initial value "0.95". Setting the "type" to "real" signals that real number are accepted as opposed to type="integer" which would accept integers only.
  </para>
  <programlisting>
--- 350,354 ----
  </programlisting>
  <para>
! Inside the <frame> we place another <checkbox> (using checked="true", we signal that checkbox should be checked by default), and a <spinbox>. The spinbox allows the user to select a value between "min" and "max" with the default/initial value "0.95". Setting the "type" to "real" signals that real numbers are accepted as opposed to type="integer" which would accept integers only.
  </para>
  <programlisting>
***************
*** 474,489 ****
  </para>
  <para>
! For instance
  </para>
! </chapter>
  
! <chapter id="embedding">
! <title>Embedding Plugins</title>
  <para>
  
  </para>
  </chapter>
  
! 
  
  <appendix id="reference">
--- 475,654 ----
  </para>
  <para>
! For instance, suppose you want to extend the t-test example used in this documentation to allow both: comparing a variable against another variable (as shown), and comparing a variable against a constant value. Now, one way of doing this would be to add a radio-control that switches between the two modes, and adding a spinbox to enter the constant value to compare against. Consider this simplified example:
  </para>
! <programlisting>
! <!DOCTYPE rkplugin>
! <document>
! 	<code file="code.php"/>
  
! 	<dialog label="T-Test">
! 		<row>
! 			<varselector id="vars"/>
! 			<column>
! 				<varslot id="x" type="numeric" source="vars" required="true" label="compare"/>
! 				<radio id="mode" label="Compare against">
! 					<option value="variable" checked="true" label="another variable (select below)"/>
! 					<option value="constant" label="a constant value (set below)"/>
! 				</radio>
! 				<varslot id="y" type="numeric" source="vars" required="true" label="variable"/>
! 				<spinbox id="constant" initial="0" label="constant" />
! 			</column>
! 		</row>
! 	</dialog>
! </document>
! </programlisting>
  <para>
+ So far so good, but there are a number of problems with this GUI. First, both the varslot and the spinbox are always shown, whereas only one of the two is really used. Worse, the varslot always requires a valid selection, even if you compare against a constant. Obviously, if we create a multi-purpose GUI like this, we want more flexibility. Enter: the <logic>-section (inserted at the same level as <code>, <dialog>, or <wizard>).
+ </para>
+ <para>
+ <programlisting>
+ 	[...]
+ 	<code file="code.php"/>
+ 
+ 	<logic>
+ 		<convert id="varmode" mode="equals" sources="mode.string" standard="variable" />
+ 		<convert id="constmode" mode="equals" sources="mode.string" standard="constant" />
+ 
+ 		<connect client="y.required" governor="varmode" />
+ 		<connect client="y.visible" governor="varmode" />
+ 
+ 		<connect client="constant.required" governor="constmode" />
+ 		<connect client="constant.visible" governor="constmode" />
+ 	</logic>
  
+ 	<dialog label="T-Test">
+ 	[...]
+ </programlisting>
+ </para>
+ <para>
+ The first two lines inside the logic section are <conver> tags. Those basically provide two new boolean (on or off, true or false) properties, which can be used later on. The first property ("varmode") is true, whenever the upper radio-button is selected and the second whenever the lower radio-button is selected. How is this done?
+ </para>
+ <para>
+ First, under sources, the "source" properties to work on are listed (in this case only one each; you could list several as sources="mode.string;somethingelse", then varmode would only be true, if both mode.string and somethingelse are equal to the string "variable"). Note that in this case we don't just write "mode" (as we would in getRK("mode"), but "mode.string". This is actually the internal way a radio control works: It has a property "string", which holds its string value. getRK ("mode") is just a shorthand, and equivalent to getRK ("mode.string"). See the reference for all properties of the different GUI elements.
+ </para>
+ <para>
+ Second, we set the mode of conversion to mode="equals". This means, we want to check, whether the sources are equal to a certain value. Finally standard is the value to compare against, so with standard="variable", we check whether the property mode.string is equal to the string "variable" (the value of the upper radio option). If it is equal, then the property varmode is true, else it is false.
+ </para>
+ <para>
+ The next line is basically the same, but reversed. Here we define a property ("constmode") which becomes true, if the second radio option is selected.
+ </para>
+ <para>
+ Now to the real stuff: We <connect> the "varmode" property to two different properties. Firstly, to y.required. This specifies, whether the varslot "y" is required or not. Secondly, to y.visible, which controls whether the varslot "y" is shown or not. Hence, if the upper radio-option is selected, the varslot "y" is required, and visible. Else it is not required and hidden.
+ </para>
+ <para>
+ We do just the reverse for the spinbox. So in effect, either the varslot is shown and required, <emphasis>or</emphasis> the spinbox is shown and required - depending on which option is selected in the radio control. The GUI is changing itself according to the radio option. Try the example, if you like.
+ </para>
+ <para>
+ Once again, for a complete list of properties, refer to the <link linkend="reference">reference</link>. One more property, however, is special in that all GUI elements have it: "enabled". This is slightly less drastic that "visible". It does not show/hide the GUI element, but only enables/disables it. Disabled elements are typically shown grayed out, and do not react to user input.
  </para>
  </chapter>
  
! <chapter id="embedding">
! <title>Embedding Plugins into Plugins</title>
! <para>
! When writing plugins, you will often find that you're creating a number of plugins that only differ in some respects, but have a lot more in common. For instance, for plotting, there are a number of generic R options that can be used with mostly all types of plots. Should you create a GUI and PHP-template for those over and over again?
! </para>
! <para>
! Obviously that would be quite a hassle. Fortunately, you don't have to do that. Rather you create the common functionality once, and later you can embed it into several plugins. In fact it is possible to embed any plugin into any other plugin, even if the original author of the embedded plugin never thought, somebody would want to embed their plugin into another one.
! </para>
! <section id="embedding_dialog">
! <title>Embedding inside a dialog</title>
! <para>
! Ok, enough said. How does it work? Simple: Just use the <embed> tag. Here's a stripped down example:
! </para>
! <programlisting>
! <dialog>
! 	<tabbook>
! 		<tab [...]>
! 			[...]
! 		</tab>
! 		<tab label="Plot Options">
! 			<embed id="plotoptions" component="rkward::plot_options"/>
! 		</tab>
! 		<tab [...]>
! 			[...]
! 		</tab>
! 	</tabbook>
! </dialog>
! </programlisting>
! <para>
! What happens here, is that the entire GUI or the plot options plugin (except of course for the standard elements like submit-button, etc.) is embedded right into your plugin (try it!).
! </para>
! <para>
! As you can see the syntax of the <embed>-tag is fairly simple. It takes an id as most elements. The parameter component specifies which plugin to embed, as defined in the <link linkend="pluginmap">.pluginmap</link> file ("rkward::plot_options" is the result of concatenating the namespace "rkward", a separator "::", and the name of the component "plot_options").
! </para>
! </section>
! <section id="embedding_code">
! <title>Code generation when embedding</title>
! <para>
! So far so good, but what about the generated code? How are the code for the embedding and embedded plugin merged? In the embedding plugin's PHP-code, simply write something like this:
! </para>
! <programlisting>
! function printout () {
! [...] ?>
! myplotfunction ([...]<? getRK ("plotoptions.code.printout"); ?>)
! <? [...]
! }
! </programlisting>
! <para>
! So essentially, we're fetching the code generated by the embedded plugin just like we're fetchting any other GUI setting. Here the string "plotoptions.code.printout" can be deparsed to: "The printout section of the generated code of the element with the id plotoptions" (plotoptions is the id we gave for the <embed>-tag above). And yes, if you want advanced control, you can even fetch the values of individual GUI elements inside the embedded plugin (but not the other way around, as the embedded plugin does not know anything about its surroundings).
! </para>
! </section>
! <section id="embedding_wizard">
! <title>Embedding inside a wizard</title>
! <para>
! If your plugin provides a wizard GUI, embedding works basically in the same way. You'll generally use:
! </para>
! <programlisting>
! 	<wizard [...]>
! 		[...]
! 		<page id="page12">
! 			[...]
! 		</page>
! 		<embed id="plotoptions" component="rkward::plot_options"/>
! 		<page id="page13">
! 			[...]
! 		</page>
! 		[...]
! 	</wizard>
! </programlisting>
! <para>
! If the embedded plugin provides a wizard interface, its pages will be inserted right between page12 and page13 of your plugin. If the embedded plugin provides a dialog interface only, a single new page will be added between your pages page12 and page13. The user will never notice.
! </para>
! </section>
! <section id="embedding_as_button">
! <title>Less embedded embedding: Further options button</title>
! <para>
! While embedding is cool, you should be careful not to overdo it. To many functions inside a GUI just make it hard to find the relevant options. Of course, sometimes you may want to embed a great deal of options (like all the options to plot ()), but as those are really optional, you don't want them prominently in your GUI.
! </para>
! <para>
! An alternative is to embed those options "as a button":
! </para>
! <programlisting>
! <dialog>
! 	<tabbook>
! 		[...]
! 		<tab label="Options">
! 			[...]
! 			<embed id="plotoptions" component="rkward::plot_options" as_button="true" label="Specify plotting options"/>
! 		</tab>
! 		[...]
! 	</tabbook>
! </dialog>
! </programlisting>
! <para>
! In this case, a single push button will be added to your plugin, labelled "Specify plotting options". When you press that button, a separate dialog will come up, with all the options of the embedded plugin. Even while this embedded GUI is not visible most of the time, you can fetch its settings just as described <link linkend="embedding_code">above</link>.
! </para>
! <para>
! <emphasis>Caution:</emphasis> Probably the "button" approach should only ever be used for plugins that can never be invalid (for missing/bad settings). Otherwise the user would not be able to submit the code, but might have a hard time finding out, the reason for that is hidden behind some button.
! </para>
! </section>
! <section id="embedding_incomplete">
! <title>Embedding/defining incomplete plugins</title>
! <para>
! Some plugins - and as a matter of fact, the plot_options used as an example above, is one of them - are not complete by themselves. They simply do not have the GUI elements to select some important values. They are meant to be used only embedded into other plugins.
! </para>
! </section>
! </chapter>
  
  <appendix id="reference">





More information about the rkward-tracker mailing list