[GRASS5] Interfaces ... (long)

Glynn Clements glynn.clements at virgin.net
Thu Jun 28 13:55:57 EDT 2001


Eric G. Miller wrote:

>   *   In some modules there is a clear dependency/conflict relationship
>       between various flags and options.  In cases I've encountered, it
>       often seems to be, you can run the command with a, b, c or with a
>       and d (but not b and c).  I think it would be valuable to be able
>       to capture this inter option/flag dependency, as better interfaces
>       could be generated.  I don't have a fully formulated suggestion
>       for this one, but it would require some significant changes.  

I think that it would be worth doing, though. I've already encountered
a few cases where the assumption that the options' "required"
attributes are independent is a nuisance. Currently you have to
specify that none are required and then signal an error if a suitable
combination isn't used.

An example would be for programs which operate on red, green and blue
maps (e.g. d.rgb, r.composite). It would be useful to allow either

	d.rgb r=red g=green b=blue
or
	d.rgb input=image

with the latter using e.g. "image.r", "image.g" and "image.b".

>       One way to look at them, is to create an option/flag grouping.
>       This should be feasible within the current DTD framework as more
>       than one "parameter-group" can exist for a given task.  However,
>       the "parameter-group" is probably too high up the chain, as we
>       would probably not want to have to duplicate common options for
>       each parameter-group.
>       
>       One way to change this in the DTD, would be to allow "parameter"
>       and "flag" elements to exist as direct children of "task" and only
>       use "parameter-group" when a set of options should be grouped
>       together *and* conflict with any other parameter-group.  The
>       G_parser() system would have to have a way to specify this
>       information.  There could be the concept of a OptionGroup, and
>       individual options could be added to OptionGroups.  
> 
>       Another way to approach, might be to add a mechanism to specify
>       more complex dependency/conflict relationships between options
>       before calling G_parser().  That is there'd be a functions like:
>       G_parser_depends (OptionOfInterest, OptionRequired),
>       G_parser_conflicts (OptionOfInterest, OptionConflicts)
>       There'd be some interaction with the "required" member for Options
>       which would need to be considered.  For instance, if a "global"
>       option has "opt->required = YES", then another option can't
>       conflict with it.  Nor, could one option require an option that
>       requires a third option that conflicts with the first.  I'm not
>       sure how you'd specify this in a DTD...
> 
>       This kind of dependency/conflict stuff can't get a bit hairy, but
>       it would provide the ability to create better user interfaces.

The most general case would be to allow the dependencies to be
specified as a boolean expression, e.g.

	input OR (red_map AND green_map AND blue_map)

However, this isn't necessarily the best method for generating a UI.
For that, explicit groups might be better, e.g.

	input_opt->required = GROUP;
	input_opt->group = 1;
	input_opt->subgroup = 1;

	r_opt->required = GROUP;
	r_opt->group = 1;
	r_opt->subgroup = 2;

	g_opt->required = GROUP;
	g_opt->group = 1;
	g_opt->subgroup = 2;

	b_opt->required = GROUP;
	b_opt->group = 1;
	b_opt->subgroup = 2;

This would result in a GUI where the group has a set of radio buttons
to choose which subgroup was active, e.g.

	<*> Input  [                 ]

	< > Red    [                 ]
	    Green  [                 ]
	    Blue   [                 ]

This is basically the boolean case restricted to a "sum of products"
form.

>   *   Returning to the problem of interactive programs...
>       This gets alot deeper into system architecture concepts, but it is
>       extremely important if we agree there should be a mechanism for
>       separating the interface from the implementation.  
>       
>       It's clear there needs to be a mechanism for a running module to
>       prompt for user action, but be able to do so in a way not tied to
>       any particular implementation (like Vask or the various G_ask_*
>       listing routines both which assume a terminal, and the first
>       assumes "curses").  We could return to XML to provide such
>       mechanisms (or at least the specifications), but it will take some
>       thought and alot of work to realize.  
> 
>       There are different types of user interaction that are often
>       required.  The simplest to deal with would probably be the Vask
>       case where the user is prompted to fill out "form" type data.
>       But, the program would have to know it wants to dump out a form
>       specification, rather than a curses interface

The existing Vask interface could remain largely unchanged. V_call()
would become a "switcher" which selects the correct input mechanism.
Similiarly for G_ask().

The main requirement is that programs only use the designated
functions to interact with the user, i.e. using G_ask() rather than
fprintf() and fgets() (or whatever).

A similar issue applies to information and warning messages (i.e. use
of G_warning() rather than writing to stderr).

>       *and* the program
>       would have to have to ability to restart where it left off
>       (consider the nature of http -- the module would have to exit,
>       then be restarted when it was called again with the form data
>       "posted").

This is where interactive programs fall down. To my mind, the only
solution is to ensure that all useful processing functionality is
available in a non-interactive manner.

>       Even if we solved the above, what about display programs that take
>       direction via "mouse clicks", or something of the nature of
>       v.digit?  Here the interaction is of a different sort, and it
>       wouldn't do for the modules to stop and start.
> 
>       I don't have much for suggestions on this last one, but it is
>       something to consider longer range.

v.digit is a special case, as it is basically a data-entry mechanism.

The cases where it might be worth changing programs to fit a more
general framework are where interaction is combined with some form of
computation.

As an example, consider d.measure. It might be worthwhile having one
program which can take a list of x,y coordinates and computed
distances and areas, and a separate program which can generate those
coordinates from user input.

In order to make mouse-driven programs fit any kind of framework, I
think that we would need to perform an audit of such programs to
determine the kind of data which they are trying to obtain, and the
type of feedback that is required in obtaining that data.

If common patterns were to emerge, it might be possible to separate
the interactive portion into routines which could obtain certain types
of data (e.g. paths, boxes, site lists). These could then form part of
any GUI front-end.

-- 
Glynn Clements <glynn.clements at virgin.net>



More information about the grass-dev mailing list