[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

One use for a proportional gadget is to let the user change some integer
value, like the red, green, and blue components of a color. This type of
prop gadget is commonly accompanied by an integer string gadget, enabling
the user to adjust one integer value by either typing the value into the
string gadget or by scrolling the prop gadget.  Because these two gadgets
reflect the value of the same integer, when the user adjusts the state of
one of the gadgets (and thus changing the integer value), the other gadget
should automatically update to reflect the new integer value.

When the user manipulates a conventional gadget, the gadget sends messages
to an IDCMP port to indicate the state change (for information on IDCMP,
see the "Intuition Input and Output Methods" chapter of this manual).  To
connect the string and prop gadgets from the previous paragraph, an
application would have to listen for the IDCMP messages from two different
gadgets, interpret the IDCMP message's meaning, and manually update the
gadgets accordingly. Essentially, the application is responsible for
"gluing" the gadgets together.  This unnecessarily complicates an
application, especially when that application already has to listen for
and interpret many other events.

Boopsi gadgets simplify this.  By setting the appropriate attributes, an
application can ask a Boopsi gadget to tell some other object when its
state changes.  One of the attributes defined by gadgetclass is ICA_TARGET
(defined in <intuition/icclass.h>).  The ICA_TARGET attribute points to
another Boopsi object.  When certain attributes in a Boopsi gadget change
(like the integer value of a prop gadget), that gadget looks to see if it
has an ICA_TARGET.  If it does, it sends the target a message telling it
to perform an OM_UPDATE method.

The OM_UPDATE method is defined by rootclass.  This is basically a special
type of OM_SET method that is used specifically to tell a Boopsi object
that another Boopsi object's state changed.  Only Boopsi objects send
OM_UPDATE messages.  Note that standard classes of Boopsi gadgets only
send out OM_UPDATE messages as a result of the user changing the state of
the gadget (scrolling the prop gadget, typing a new number into an integer
gadget, etc.).  These gadgets do not send out OM_UPDATE messages when they
receive OM_SET or OM_UPDATE messages.

A Boopsi propgclass object has only one attribute that triggers it to send
an OM_UPDATE request: PGA_Top. This attribute contains the integer value
of the prop gadget.  Every time the user moves a prop gadget, the PGA_Top
attribute changes.  If the prop gadget has an ICA_TARGET, the prop gadget
will tell the target object that the PGA_Top value has changed.

A Boopsi integer string gadget (a strgclass object) also has only one
attribute that triggers it to send an OM_UPDATE request: STRINGA_LongVal.
value contains the integer value of the integer string gadget.  Like
the prop gadget, if the integer string gadget has an ICA_TARGET, when the
user changes the gadget's integer value (STRINGA_LongVal), the string
gadget will tell the target object that the STRINGA_LongVal value has
changed.

When a Boopsi gadget sends an OM_UPDATE message, it passes the ID of the
attribute that changed plus that attribute's new value.  For example, if
the user typed a 25 into a Boopsi integer string gadget, that gadget would
send an OM_UPDATE message to its ICA_TARGET saying in essence, "Hey,
STRINGA_LongVal is 25".

If this string gadget's ICA_TARGET is a propgclass object, the propgclass
object will become confused because it has no idea what a STRINGA_LongVal
attribute is.  The string gadget needs to map its STRINGA_LongVal ID to
the PGA_Top ID.  This is what the ICA_MAP attribute is for.

The ICA_MAP attribute is defined by gadgetclass (it is also defined for
icclass--more on that later).  It accepts a tag list of attribute
mappings.  When a gadget sends out an OM_UPDATE message, it uses this map
to translate a specific attribute ID to another attribute ID, without
changing the value of the attribute.  Each TagItem in the ICA_MAP makes up
a single attribute mapping. The TagItem.ti_Tag of the mapping is the ID of
an attribute to translate.  The gadget translates that attribute ID to the
attribute ID in TagItem.ti_Data.  For example, an ICA_MAP that maps a
string gadget's STRINGA_LongVal attribute to a prop gadget's PGA_Top
attribute looks like this:

    struct TagItem slidertostring[] = {
        {PGA_Top, STRINGA_LongVal},
        {TAG_END, }
    };

Note that it is OK to have an ICA_TARGET without having an ICA_MAP.  In
cases where a gadget and its ICA_TARGET have a set of attributes in
common, it would be unnecessary to use an ICA_MAP to match a gadget's
attributes, as they already match.

The following example, Talk2boopsi.c, creates a prop gadget and an integer
string gadget which update each other without the example program having
to process any messages from them.

     Talk2boopsi.c