@database "select"
@master "Ram Disk:select.doc"

@Node Main "select.doc"
    @{" --background-- " Link "--background--"}
    @{" select.gadget() " Link "select.gadget()"}
    @{" ClearSelectGadget() " Link "ClearSelectGadget()"}
    @{" GetSGAttr() " Link "GetSGAttr()"}
    @{" InitSelectGadgetA() " Link "InitSelectGadgetA()"}
    @{" ObtainSelectGClass() " Link "ObtainSelectGClass()"}
    @{" SetSGAttrsA() " Link "SetSGAttrsA()"}
@EndNode

@Node "--background--" "select.gadget/--background--"

   @{" Description         " Link DESCRIPTION}
   @{" Class documentation " Link DOCUMENTATION}
   @{" User configuration  " Link USERCONF} (and programming style)
   @{" Future plans        " Link TODO}

@EndNode

@Node DESCRIPTION "Description"

@{b}DESCRIPTION@{ub}

The select.gadget is a shared library which, when opened, adds to the system
a public BOOPSI gadget class called "selectgclass". This class implements a
button-like selection gadget, with features similar to those of a traditional
GadTools cycle gadget, but with the additional ability to open, when pressed,
a pop-up menu which allows the user to pick his choice more easily.

The look and behavior of the gadget and its pop-up menu can be configured
using the attribute tags of the class.

The library is freeware; if you use it, you are allowed to distribute it
with your software.

Some highlights:

- A delay can be set for the appearance of the pop-up menu, allowing for a
  gadget which reacts like a normal cycle gadget upon "quick" clicks, and
  like a pop-up gadget if the mouse button is kept pressed a little longer.

- It is optionally possible to have a "sticky" pop-up menu which remains
  open when the mouse button is released.

- The gadget can be made "quiet", that is, the currently selected item can be
  not displayed. Useful to attach a small pop-up button to string gadgets.

- The gadget can be configured to always behave like a cycle gadget, and
  even like a plain button gadget.

- The gadget can broadcast changes in its value to target objects via the
  BOOPSI notification system.

- All changes done with @{"SetGadgetAttrsA()" Link "intuition/SetGadgetAttrsA()"} to the gadget's position, size
  and look are visually executed in real-time.

- The gadget's dispatcher is able to swap the stack when needed.

- The gadget can be added to requesters and window borders.

- The pop-up menu can have a drop shadow.

- The gadget's "pop-up" symbol can be placed at the left side, at the right
  side, or it can also not appear at all; its width is also configurable.
  The gadget's default imagery for the symbol is fully scalable, and it can
  be replaced by the application with a custom image.

- The default values for unspecified attributes can be globally set by the
  user with an ASCII preferences file; the changes are applied in real-time
  (to gadgets created afterwards) via file notification.

Furthermore, the library offers some functions which allow to "transform"
a normal gadget into a custom gadget having (almost) the same features of
the "selectgclass" gadgets.

This way it's possible, for example, to create GadTools GENERIC_KIND gadgets
and turn them into pop-up gadgets, obtaining all the benefits of this type
of gadgets while also keeping the benefits of the GadTools automatic gadget
creation (and deletion) system.

Lastly, this gadget class supports VisualPrefs and takes full advantage of
the graphic enhancements it brings to the system.
@EndNode

@node DOCUMENTATION "Class documentation"

@{b}CLASS DOCUMENTATION@{ub}

@{b}Class:@{ub}        selectgclass
@{b}Superclass:@{ub}   gadgetclass
@{b}Include File:@{ub} <gadgets/select.h>

A BOOPSI popup gadget which can also behave as a GadTools-like cycle gadget
or even as a normal button gadget. The selectgclass gadget keeps its current
active item value in its SGA_Active attribute, and when it changes because
of user's interaction a notification message is sent to its target and also
(optionally) an IDCMP_GADGETUP message is sent to its window's UserPort.

@{b}New Methods:@{ub}

None.

@{b}Changed Methods:@{ub}

OM_NEW - After creation of the gadget by the superclass, this method
initializes the "selectgclass" instance data on the basis of the contents
of the attributes tag list.

OM_DISPOSE - This method frees all the resources allocated in the OM_NEW
method.

OM_SET, OM_UPDATE - The gadget will automatically refresh its graphic
appearance to reflect any changes to visual attributes, such as the active
item, the gadget position and size, and the gadget text. In particular,
when the gadget is moved, it first erases itself at the old position.

GM_RENDER - The rendering of the various "selectgclass" gadget components
(frame, symbol, label, text) is made in a very optimized way. The gadget
clips its graphics at the window borders, and avoids as much as possible
to redraw a single pixel more than once. If gpRender.gpr_Redraw has the
value GREDRAW_UPDATE the gadget redraws only the frame and its contents,
otherwise it also redraws the text.

GM_HITTEST - This method currently always returns GMR_GADGETHIT, but don't
count on this being the case also in future versions.

GM_GOACTIVE - In this method some precalculations are made and cached, to
speed up the GM_HANDLEINPUT method.

GM_HANDLEINPUT - If the user clicks with the mouse select button on the
"pop-up" zone of the gadget (which can be the entire gadget box, or just
a part of it, depending on the value of the SGA_FullPopUp tag), an internal
timer starts.

If the button is released before the pop-up delay (set with SGA_PopUpDelay)
expires, the gadget behaves exactly as a GadTools cycle gadget would: if the
mouse pointer was within the gadget box when the button was released, the
gadget's active item changes, and the change is reported to the application
via an IDCMP_GADGETUP @{"IntuiMessage" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 679} and/or to the gadget's target object via
an OM_UPDATE message.

If, instead, the mouse button is kept pressed long enough, a pop-up menu
appears, showing all the available items. However, it the gadget has too few
items (the threshold can be set with the SGA_MinItems tag) the menu doesn't
appear, and the gadget keeps behaving like a cycle gadget.

When the menu is displayed, the user can select any of the displayed items
just by moving the mouse pointer on it and releasing the mouse select button.
Alternatively, if the pop-up menu is of the "sticky" type, the user must
first release the mouse button, then move the pointer on the desired choice
and press the button again.

If the selected item is different from the previously active one, or if
the SGA_ReportAll attribute is set to TRUE, the new active value is reported
to the application via an IDCMP_GADGETUP @{"IntuiMessage" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 679} and/or to the gadget's
target object via an OM_UPDATE message.

If the mouse select button is initially clicked with the pointer not on
the "pop-up" zone of the gadget, the pop-up menu doesn't appear, and the
gadget behaves like a GadTools cycle gadget, no matter how long the button
is kept pressed.

As with GadTools, a SHIFT qualifier causes the gadget to cycle backwards.

The gadget reports changes in its SGA_Active attribute value to the
application by sending an IDCMP_GADGETUP @{"IntuiMessage" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 679} to the UserPort
of its window. The IntuiMessage.Code field contains the new value of
the attribute.

The gadget reports changes in its SGA_Active attribute value to its
target object by sending it an OM_UPDATE message. The message's attribute
tag list contains the new value of the attribute and the ID of the gadget.

Any operation being made with the "selectgclass" gadget can always be aborted
by pressing the right (menu) button of the mouse.

GM_GOINACTIVE - This method does a clean-up after the GM_GOACTIVE method.

GM_LAYOUT - In this method, a "selectgclass" gadget does all necessary
calculations to prepare itself for rendering and user interaction.
This method fully support the Intuition relativity flags (GFLG_RELRIGHT,
GFLG_RELBOTTOM, GFLG_RELWIDTH and GFLG_RELHEIGHT).

@{b}Attributes:@{ub}

GA_Image (IS) - The image the gadget will use to render its frame. If this
                attribute is not specified, or if it's NULL, a default image
                will be used (namely, an instance of "frameiclass").
                If it's set to ~0 (or -1) no image will be rendered.
                The gadget renders its frame image with the IM_DRAWFRAME
                method when possible, so it would be a good idea to have
                your custom image support this.
                Changing this attribute causes the gadget to be redrawn.

GA_Text, GA_IntuiText, GA_LabelImage (IS) - The gadget supports all of these
                                            methods of specifying a text.
                                            Changing one of these attributes
                                            causes the gadget to be redrawn.
                                            See also SGA_TextPlace (below).

GA_Left, GA_RelRight, GA_Top, GA_RelBottom (IS) - The gadget supports both
                                                  absolute and relative
                                                  positioning. Changing one
                                                  of these attributes causes
                                                  the gadget to be redrawn,
                                                  with its old imagery being
                                                  erased first.

GA_Width, GA_RelWidth, GA_Height, GA_RelHeight (IS) - The gadget supports
                                                      both absolute and
                                                      relative sizing.
                                                      Changing one of these
                                                      attributes causes the
                                                      gadget to be redrawn,
                                                      with its old imagery
                                                      being erased first.

GA_DrawInfo (I) - A pointer to your screen's @{"DrawInfo" Link "TEXT_INCLUDE:intuition/screens.h/Main" 60} structure. If this
                  attribute is specified, and the tag list doesn't contain
                  any explicit information about the gadget's size, the
                  gadget will automatically size itself just large enough to
                  frame its contents. This can work for just one axis, or
                  both, depending on which ones have an explicitly specified
                  size. This attribute is only valid at creation time; you
                  don't need to specify it if you do not want the automatic
                  sizing feature.

SGA_Active (ISGNU) - The index number (starting from zero) of the current
                     active item. The default value is zero.
                     Changing this attribute causes the gadget to be redrawn.

SGA_Labels (ISU) - A NULL-terminated string array containing all the item
                   labels for the gadget. It can safely be empty. If this
                   attribute is not specified, or if it's NULL, the gadget
                   will look and behave like a traditional button gadget.
                   Changing this attribute causes the gadget to be redrawn.

SGA_MinItems (ISGU) - The minimum number of items the gadget must have for
                      the pop-up menu to appear. If the items are fewer than
                      this, the gadget will always behave like a traditional
                      GadTools cycle gadget. The default is zero.

SGA_FullPopUp (ISU) - If TRUE, clicking anywhere on the gadget box will
                      cause the pop-up menu to appear (after the requested
                      delay). If FALSE, clicking on the "symbol box" (if
                      one exists) will make the gadget behave like a GadTools
                      cycle gadget. Defaults to FALSE.

SGA_PopUpDelay (ISU) - The amount of time (in milliseconds) the gadget must
                       remain pressed for the pop-up menu to appear. If this
                       is zero, the pop-up menu will appear immediately and
                       the gadget won't even change to its "pressed" state.
                       Defaults to zero.

SGA_PopUpPos (ISU) - This attribute determines where the pop-up menu is to
                     appear, relative to the gadget's position. It may have
                     four different values:
                     SGPOS_ONITEM - position the menu so that the the active
                                    item is under the mouse pointer.
                     SGPOS_ONTOP - always align the top edge of the menu with
                                   the top edge of the gadget.
                     SGPOS_BELOW - place the menu just below the gadget.
                     SGPOS_RIGHT - place the menu at the right side of gadget,
                                   aligning its top edge with the gadget's
                                   top edge.
                     With the exception of SGPOS_RIGHT, all the values center
                     the menu horizontally on the "popup" zone of the gadget.
                     The default is SGPOS_ONITEM.

SGA_Sticky (ISU) - If FALSE, the pop-up menu will close as soon as the user
                   releases the mouse button. If TRUE, the menu will remain
                   open after the button is released, and will close when the
                   user clicks on it to select an item, or somewhere else to
                   abort the operation. Defaults to FALSE.
                   Changing this attribute causes the gadget to be redrawn
                   (to change the symbol image), unless you are using a
                   custom symbol.

SGA_TextAttr (ISU) - Pointer to a @{"TextAttr" Link "TEXT_INCLUDE:graphics/text.h/Main" 66} structure describing the font
                     to be used for the gadget's text and labels. The font
                     must be already in memory and openable with OpenFont();
                     if not, the screen font will be used instead.
                     This attribute is overridden by SGA_TextFont.
                     Changing this attribute causes the gadget to be redrawn,
                     unless there's a valid font specified with SGA_TextFont.

SGA_TextFont (ISU) - Pointer to a @{"TextFont" Link "TEXT_INCLUDE:graphics/text.h/Main" 90} structure which is to be used for
                     rendering the gadget's text and labels. This overrides
                     the SGA_TextAttr attribute. If both attributes are NULL
                     or not specified, the screen font will be used.
                     The font whose pointer you pass with this tag must
                     remain open for the whole life of the gadget.
                     Changing this attribute causes the gadget to be redrawn.

SGA_TextPlace (ISGU) - The position at which the gadget's text is to be
                       rendered. It can assume one of the five PLACETEXT_#?
                       values defined in @{"<libraries/gadtools.h>" Link "TEXT_INCLUDE:libraries/gadtools.h/Main" 0}. If this is
                       not specified, PLACETEXT_LEFT is assumed, unless the
                       gadget has no items (that is, it's a button gadget)
                       in which case PLACETEXT_IN is assumed.
                       This works also if the text is really an image label.
                       Changing this attribute causes the gadget to be
                       redrawn, with the text in the new position.
                       Note: currenty this attribute MUST be specified if the
                       gadget uses an @{"IntuiText" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 572} for its text, whereas it can
                       be optional if the text is a string or an image label.

SGA_Underscore (ISU) - The symbol preceding the character in the gadget text
                       to be underscored. This can be to indicate keyboard
                       equivalents for gadgets (note that "selectgclass" does
                       not process the keys; it just displays the underscore).
                       This attribute is only used if the gadget text is a
                       simple string; if you use an @{"IntuiText" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 572} or an image,
                       you must provide your own underscoring.
                       The value of this attribute is a simple UBYTE.
                       Changing this attribute causes the gadget to be
                       redrawn.

SGA_Justify (ISU) - The alignment of the active label within the "text zone"
                    of the gadget box. It can be SGJ_LEFT, SGJ_CENTER or
                    SGJ_RIGHT. The default is SGJ_CENTER.
                    Changing this attribute causes the gadget to be redrawn.
                    Note: SGJ_RIGHT is not yet implemented.

SGA_Quiet (ISU) - If TRUE, the gadget's active label will not be displayed
                  within the gadget box. Defaults to FALSE.
                  Changing this attribute causes the gadget to be redrawn.

SGA_Symbol (ISU) - Pointer to a standard or BOOPSI image structure, to be
                   used as the "pop-up" symbol (akin to the "cycle" symbol
                   of GadTools cycle gadgets) which is usually displayed
                   at the left or right side of a "selectgclass" gadget.
                   The image, if BOOPSI, is rendered within the symbol box
                   using the IM_DRAWFRAME method, so try to support this.
                   If NULL or not specified, a default (scalable) internal
                   image will be used, whose look depends on the gadget type
                   (sticky or non-sticky).
                   If this is ~0 (or -1) no symbol will be displayed.
                   Changing this attribute causes the gadget to be redrawn.

SGA_SymbolWidth (ISGU) - The width of the "symbol box", that is, the part of
                         the gadget box (usually delimited by a separator
                         line) which contains the "pop-up" symbol. It is
                         advised not to make it too wide, or there could be
                         insufficient room for the gadget's active label.
                         The default is 21 (like for GadTools cycle gadgets).
                         Changing this attribute causes the gadget to be
                         redrawn.

SGA_SymbolOnly (ISU) - If TRUE, only the symbol box will be selectable, while
                       the rest of the gadget will appear recessed and will
                       be read-only. Defaults to FALSE.
                       Changing this attribute causes the gadget to be
                       redrawn.

SGA_Separator (ISU) - If TRUE, a recessed separator line will be drawn
                      between the symbol and the active label in the gadget
                      box. Defaults to TRUE.
                      Changing this attribute causes the gadget to be redrawn.

SGA_ListFrame (ISU) - Pointer to a standard or BOOPSI image to be used as
                      the background of the pop-up menu panel. When possible
                      it is rendered with the IM_DRAWFRAME method, so try to
                      support this. If NULL or not specified, a default image
                      will be used (an instance of "frameiclass").

SGA_DropShadow (ISU) - If TRUE, a four-pixel thick dithered drop shadow will
                       appear under the pop-up menu. Defaults to FALSE.

SGA_ItemSpacing (ISU) - The number of pixels which is to be added to the
                        gadget's font height in order to determine the height
                        of an item in the pop-up menu. The result of the sum
                        will be ignored if it is smaller than the value of
                        the SGA_ItemHeight attribute (see below). The default
                        is zero.

SGA_ItemHeight (ISU) - The exact height of each item in the pop-up menu.
                       It can never be less than the gadget's font height
                       plus the value of the SGA_ItemSpacing attribute.
                       Defaults to the gadget's font height plus the value
                       of the SGA_ItemSpacing attribute.

SGA_ListJustify (ISU) - The alignment of labels within the pop-up menu panel.
                        It can be SGJ_LEFT, SGJ_CENTER or SGJ_RIGHT. The
                        default is SGJ_CENTER.
                        Note: SGJ_RIGHT is not yet implemented.

SGA_ActivePens (ISU) - Pointer to an array of four UWORDs containing the
                       pen numbers to be used for rendering the active item
                       in the pop-up menu panel. The meaning of the array
                       index is: 0 - color of the text; 1 - color of the
                       background; 2 - color of the bright edges; 3 - color
                       of the dark edges.
                       These are actual color numbers, not Intuition pen
                       numbers.
                       Defaults to using the colors of FILLTEXTPEN, FILLPEN,
                       SHINEPEN and SHADOWPEN (although the presence of the
                       VisualPrefs patch might change these defaults).

SGA_ActiveBox (ISU) - If this is not zero, the active item in the pop-up
                      menu panel will have a 3D frame around it. The frame
                      will be recessed if this attribute is -1, otherwise
                      it will be raised. The colors are determined with the
                      SGA_ActivePens tag. Defaults to zero (no frame).

SGA_BorderSize (ISU) - The thickness of the border to be left between the
                       edges of the pop-up menu panel and the displayed
                       labels. If it is set to -1, a suitable value will be
                       chosen automatically. Defaults to -1.

SGA_FullWidth (ISU) - If TRUE, the pop-up menu will have the same width of
                      the entire gadget; if FALSE, it will have the width of
                      the gadget minus the width of the symbol box. Defaults
                      to FALSE.

SGA_FollowMode (ISU) - Determines the behavior of the pop-up menu when the
                       mouse pointer goes out of its boundaries. There are
                       three possible values:
                       SGFM_NONE - the active item becomes not highlighted.
                       SGFM_KEEP - the active item remains highlighted, but
                                   doesn't change until the pointer returns
                                   on the panel.
                       SGFM_FULL - the active item remains highlighted, and
                                   can also change if the user moves the
                                   pointer up and down, even if outside of
                                   the menu panel.
                       If the gadget is not sticky, and the user lets go of
                       the mouse select button while the pointer is outside
                       of the menu panel, the currently highlighted item will
                       be selected, if there is one.
                       The default is SGFM_NONE.

SGA_ReportAll (ISU) - If TRUE, the gadget reports the selection of an item
                      even if it was already the active item. If FALSE, a
                      selection is only reported when the active item
                      actually changes. Defaults to FALSE.
                      Note: if there are no items (that is, if the gadget
                      is really a button gadget) this attribute is currently
                      ignored, and assumed TRUE.

SGA_Refresh (SU) - This is not a real attribute; if you pass this tag with
                   a value of TRUE, it will force an immediate refresh of the
                   gadget's imagery. This is only useful for custom select
                   gadgets obtained with the @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"} function, as
                   the usual @{"RefreshGadgets()" Link "intuition/RefreshGadgets()"} and @{"RefreshGList()" Link "intuition/RefreshGList()"} functions
                   aren't always sufficient to refresh them correctly.
                   Real "selectgclass" BOOPSI gadgets shouldn't need this tag.
@EndNode

@Node USERCONF "User configuration and programming style"

@{b}USER CONFIGURATION AND PROGRAMMING STYLE@{ub}

Although the "selectgclass" class offers many attributes to customize its
look and behavior, programmers should not explicitly set the value of the
ones which don't influence the working of their applications, or else the
user would be confused by a multitude of differently-looking gadgets.

Usually, the only attributes you really need to specify in your code are
SGA_Active, SGA_Labels, SGA_TextPlace, SGA_Underscore, SGA_Quiet, SGA_Symbol,
SGA_ListFrame and SGA_ReportAll (plus the various GA_#? ones).
If you also use SGA_TextAttr or SGA_TextFont, it would be a good idea to
offer the user a way to choose the font and size to be used.

Of course, nothing stops you from using other attributes too, but it's a
better style to do so only when it's really needed. For attributes which
are transparent to your application, it is advised that you respect the
default values.

Such default values, for the most significant attributes defining the look
and feel of the gadgets, can be globally set by the user in a preferences
file, called "ENV:Gadgets/select.prefs".

The attribute values found in the preferences file override the built-in
default values for the corresponding tags; if an attribute isn't present
in the file, or if the file is not found, it will keep using the value
most recently set (the initial one being the built-in default).

As the preferences file is just ASCII text, the user can edit it by hand
to change the desired attributes. The format of the file is very simple; it
is a list of tool types named exactly like the corresponding "selectgclass"
tags, minus the SGA_ prefix.

An example of file would be:

   ItemSpacing=3
   FullWidth=1
   PopUpDelay=250

As of now, the attributes settable by the user are the following ones ("inf"
means "infinite"):

Attribute     Range      Type       Default

MinItems      [ 1..inf]  (integer)  1
FullPopUp     [ 0, 1  ]  (boolean)  0
PopUpDelay    [ 0..inf]  (integer)  0
PopUpPos      [ 0..3  ]  (integer)  0
Sticky        [ 0, 1  ]  (boolean)  0
Justify       [ 0..2  ]  (integer)  1
Separator     [ 0, 1  ]  (boolean)  1
DropShadow    [ 0, 1  ]  (boolean)  0
ItemSpacing   [ 0..inf]  (integer)  0
ListJustify   [ 0..2  ]  (integer)  1
ActiveBox     [-1..1  ]  (integer)  0
BorderSize    [-1..inf]  (integer) -1
FullWidth     [ 0, 1  ]  (boolean)  0
FollowMode    [ 0..2  ]  (integer)  0
@EndNode

@Node TODO "To do"

@{b}TO DO@{ub}

Future releases should add the following features:

 o More attributes globally settable by the user.

 o Ability to display read-only pop-up menus.

 o Ability to generate "repeat" messages if the gadget is kept pressed for
   a while (only when it's a button gadget). Useful for making arrow buttons.

 o Ability to only display the menu on a button release. Would make sense
   for "sticky" gadgets.

 o Text clipping for the gadget item labels.

 o Some more code optimization.

@EndNode

@Node "select.gadget()" "select.gadget/select.gadget"

@{b}   NAME@{ub}
      select.gadget -- create a pop-up, cycle or button BOOPSI gadget

@{b}   FUNCTION@{ub}
      The select.gadget shared library implements a public BOOPSI gadget
      class, called "selectgclass", which provides gadgets with the ability
      to display a pop-up menu allowing the user to pick up a choice among
      a number of alternatives.
      The "selectgclass" gadgets can also be used as standard GadTools-like
      cycle gadgets, or even as simple button gadgets.
      Nearly every aspect of their look and behavior can be configured
      using tag items which give access to the class attributes.

      For a complete description of the "selectgclass" class and its features,
      see the class reference documentation in the @{"--background--" Link "--background--"} paragraph.

      The library also supplies some functions allowing to modify an
      existing, non-BOOPSI gadget in order to make it a custom gadget
      using the hook function of "selectgclass". This makes it possible
      to use normal gadgets, such as GadTools GENERIC_KIND ones, as if
      they were "selectgclass" BOOPSI gadgets (with some minor limitations,
      mainly the lack of notification abilities).

      To be able to create and use "selectgclass" objects in an application,
      you first have to open the select.gadget library with @{"OpenLibrary()" Link "exec/OpenLibrary()"}.
      Once you have done this, you shouldn't close the library until all of
      your "selectgclass" objects have been freed.

@{b}   TAGS@{ub}
      For the full list of "selectgclass" attributes, see the class reference
      documentation in the @{"--background--" Link "--background--"} paragraph.

@{b}   NOTES@{ub}
      The "selectgclass" gadget class currently does not support adding
      gadgets to a screen titlebar. This feature shouldn't be needed anyway.

@{b}   WARNING@{ub}
      Don't close the select.gadget library if you still have some instances
      of "selectgclass" gadgets hanging around!

@{b}   BUGS@{ub}
      None known.

@EndNode

@Node "ClearSelectGadget()" "select.gadget/ClearSelectGadget"

@{b}   NAME@{ub}
      ClearSelectGadget -- strip a gadget of all additional information.

@{b}   SYNOPSIS@{ub}
      ClearSelectGadget(gadget);
                        A0

      void ClearSelectGadget(struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *);

@{b}   FUNCTION@{ub}
      Strips a gadget of all the addition information which was added by
      @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}, and restores it (as much as possible) to its
      former state. You should only call this function on gadgets that were
      successfully modified by @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}, and call it only once.

@{b}   INPUTS@{ub}
      gadget - pointer to a custom gadget initialized by @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}

@{b}   NOTES@{ub}
      Once cleared, the gadget can still be used as a traditional gadget,
      although in most cases this probably won't make much sense.

@{b}   BUGS@{ub}
      None known.

@{b}   SEE ALSO@{ub}
      @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}

@EndNode

@Node "GetSGAttr()" "select.gadget/GetSGAttr"

@{b}   NAME@{ub}
      GetSGAttr -- get value of an attribute of a non-BOOPSI select gadget.

@{b}   SYNOPSIS@{ub}
      result = GetSGAttr(attrid, gadget, storageptr);
      D0                 D0      A0      A1

      ULONG GetSGAttr(ULONG, struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *, ULONG *);

@{b}   FUNCTION@{ub}
      Inquires from the specified gadget the value of the specified
      attribute. The gadget must be a non-BOOPSI gadget successfully
      modified by @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}, and the attribute must be specific
      to "selectgclass". Do not attempt to get standard "gadgetclass"
      attributes with this function.

      You always pass the address of a LONG variable, which will receive
      the same value that would be passed to @{"SetSGAttrsA()" Link "SetSGAttrsA()"} in the ti_Data
      portion of a @{"TagItem" Link "TEXT_INCLUDE:utility/tagitem.h/Main" 31} element.

      Not all attributes will respond to this function. Those which do are
      marked with the "G" applicability flag in the "Attributes" list found
      in the class reference documentation (see @{"--background--" Link "--background--"} paragraph).

@{b}   INPUTS@{ub}
      attrid - an attribute tag ID understood by "selectgclass"
      gadget - pointer to a custom select gadget
      storageptr - pointer to appropriate storage for the answer

@{b}   RESULT@{ub}
      result - FALSE if the inquiries of the specified attribute are not
               provided by "selectgclass", TRUE otherwise

@{b}   NOTES@{ub}
      Don't call this function on real BOOPSI "selectgclass" objects; use
      @{"intuition.library/GetAttr()" Link "intuition/GetAttr()"} instead.

@{b}   BUGS@{ub}
      None known.

@{b}   SEE ALSO@{ub}
      @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}, @{"ClearSelectGadget()" Link "ClearSelectGadget()"}, @{"SetSGAttrsA()" Link "SetSGAttrsA()"}

@EndNode

@Node "InitSelectGadgetA()" "select.gadget/InitSelectGadgetA"

@{b}   NAME@{ub}
      InitSelectGadgetA -- change a gadget into a "selectgclass"-like gadget.
      InitSelectGadget -- varargs stub for InitSelectGadgetA().

@{b}   SYNOPSIS@{ub}
      success = InitSelectGadgetA(gadget, flags, taglist)
      D0                          A0      D0     A1

      ULONG InitSelectGadgetA(struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *, ULONG, struct @{"TagItem" Link "TEXT_INCLUDE:utility/tagitem.h/Main" 31} *);

      success = InitSelectGadget(gadget, flags, firsttag, ...)

      ULONG InitSelectGadget(struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *, ULONG, Tag, ...);

@{b}   FUNCTION@{ub}
      The purpose of this function is to modify an already existing gadget
      in order to make it a custom gadget which uses the same hook function
      used by the "selectgclass" BOOPSI gadgets.

      This function can be very useful if you have already written a program
      using a non-BOOPSI framework for its GUI (such as GadTools), as it
      allows you to make your program use the "select" gadgets without having
      to intermix BOOPSI code with the already existing non-BOOPSI code.

      In the case of GadTools, for example, you could create GENERIC_KIND
      gadgets instead of CYCLE_KIND gadgets, and later use InitSelectGadgetA()
      to turn them into pop-up gadgets. You would then continue handling
      your interface exactly as before, and once you are done with your
      gadgets you would just have to restore them to their original state
      (using the @{"ClearSelectGadget()" Link "ClearSelectGadget()"} function) before deleting them as usual
      with @{"gadtools.library/FreeGadgets()" Link "gadtools/FreeGadgets()"}.

      InitSelectGadgetA() does all necessary allocations, and appends some
      information to the gadget structure. This information is initialized
      on the basis of the attribute/value couples you pass in the tag list.
      The tag list can only contain attributes specific to "selectgclass"
      (SGA_#?), with the _only_ exception being the "gadgetclass" GA_Image
      attribute, which can be passed to the function.
      Every other "standard" gadget attribute (GA_#?) can't be passed to
      InitSelectGadgetA(), but must be set in the gadget structure by hand.

      However, once the structure has been modified by InitSelectGadgetA(),
      and until it is restored by @{"ClearSelectGadget()" Link "ClearSelectGadget()"}, some restrictions
      apply to what you're allowed to do with its fields.

      More precisely, you may read and write the following fields ONLY:

      NextGadget
      LeftEdge, TopEdge, Width, Height
      GadgetText
      GadgetID
      UserData
      BoundsLeftEdge, BoundsTopEdge, BoundsWidth, BoundsHeight

      You may also read, set and clear the following flag bits:

      GFLG_RELBOTTOM, GFLG_RELRIGHT, GFLG_RELWIDTH, GFLG_RELHEIGHT
      GFLG_DISABLED
      GFLG_LABELSTRING, GFLG_LABELIMAGE
      GACT_RELVERIFY
      GMORE_GADGETHELP

      The following flag bits are read-only:

      GFLG_IMAGEDISABLE
      GFLG_EXTENDED
      GACT_LEFTBORDER, GACT_TOPBORDER, GACT_RIGHTBORDER, GACT_BOTTOMBORDER
      GACT_ENDGADGET
      GTYP_SCRGADGET (not supported yet)
      GTYP_GZZGADGET
      GTYP_REQGADGET
      GMORE_BOUNDS

      All the above public fields and flag bits, even the read-only ones, may
      be set BEFORE calling InitSelectGadgetA(), which will preserve them.
      The only exception is the GACT_RELVERIFY bit: the function will always
      set it, but you can clear it later (doesn't make much sense though,
      as you would be no longer able to hear anything from the gadget).

      Note well: all remaining fields and flag bits are considered PRIVATE
      and should NOT be used nor relied on.

      To set/change the gadget's image, always use the GA_Image tag. Don't
      touch the GadgetRender field!

      Also, if you modify by hand some values in the gadget structure which
      could cause a change in the gadget visual appearance, such as its
      position, size or text, you can force a refresh of the gadget by
      calling @{"SetSGAttrsA()" Link "SetSGAttrsA()"} with the couple { SGA_Refresh, TRUE }. Using
      @{"RefreshGadgets()" Link "intuition/RefreshGadgets()"} or @{"RefreshGList()" Link "intuition/RefreshGList()"} is not sufficient in this case.

      Once your custom select gadget is no longer needed, you should strip it
      of all the added information by using the @{"ClearSelectGadget()" Link "ClearSelectGadget()"} function.
      This will turn the gadget back into whatever it was before you called
      InitSelectGadgetA().

@{b}   INPUTS@{ub}
      gadget - pointer to a non-BOOPSI gadget which will be transformed into
               a custom gadget using the hook function of "selectgclass"; it
               can safely be NULL, in which case the function returns failure
      flags - reserved for future use; please set this to zero for now
      taglist - pointer to an array of tags providing extra parameters, or
                NULL

@{b}   TAGS@{ub}
      For the full list of "selectgclass" attributes, see the class reference
      documentation in the @{"--background--" Link "--background--"} paragraph.

@{b}   RESULT@{ub}
      success - TRUE if all went ok, FALSE otherwise. If FALSE the gadget
                has not been changed, so you don't have to clear it with
                @{"ClearSelectGadget()" Link "ClearSelectGadget()"}

@{b}   EXAMPLE@{ub}
      Your already existing GadTools code might be looking like this:

         ...
         newgadget.ng_GadgetText = "Qualifier:";
         newgadget.ng_Flags = PLACETEXT_ABOVE;
         ...
         gad = CreateGadget(CYCLE_KIND,gad,&newgadget,GTCY_Labels,labels,
                                                      GTCY_Active,active,
                                                      TAG_END);
         ...


      To use the "selectgclass" features, you could modify it this way:

         ...
         newgadget.ng_GadgetText = "Qualifier:";
         ...
         gad = CreateGadget(GENERIC_KIND,gad,&newgadget,TAG_END);

         if (!InitSelectGadget(gad,0L,SGA_Labels,labels,
                                      SGA_Active,active,
                                      SGA_TextPlace,PLACETEXT_ABOVE,
                                      TAG_END))
         {
            gad = NULL;  // From now on, all CreateGadget() calls will fail
         }

         ...

@{b}   BUGS@{ub}
      None known.

@{b}   SEE ALSO@{ub}
      @{"ClearSelectGadget()" Link "ClearSelectGadget()"}

@EndNode

@Node "ObtainSelectGClass()" "select.gadget/ObtainSelectGClass"

@{b}   NAME@{ub}
      ObtainSelectGClass -- return a pointer to "selectgclass".

@{b}   SYNOPSIS@{ub}
      sgclass = ObtainSelectGClass()
      D0

      Class *ObtainSelectGClass(void);

@{b}   FUNCTION@{ub}
      Returns a pointer to the class implemented by the select.gadget, called
      "selectgclass". Use this pointer with care, and do not reference it
      after you've closed the select.gadget library.

@{b}   INPUTS@{ub}
      none

@{b}   RESULT@{ub}
      sgclass - pointer to the class

@{b}   BUGS@{ub}
      None known.

@{b}   SEE ALSO@{ub}

@EndNode

@Node "SetSGAttrsA()" "select.gadget/SetSGAttrsA"

@{b}   NAME@{ub}
      SetSGAttrsA -- change the attributes of a non-BOOPSI select gadget.
      SetSGAttrs -- varargs stub for SetSGAttrsA().

@{b}   SYNOPSIS@{ub}
      result = SetSGAttrsA(gadget, window, requester, flags, taglist)
      D0                   A0      A1      A2         D0     A3

      ULONG SetSGAttrsA(struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *, struct @{"Window" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 797} *,
                        struct @{"Requester" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 145} *, ULONG, struct @{"TagItem" Link "TEXT_INCLUDE:utility/tagitem.h/Main" 31} *);

      result = SetSGAttrs(gadget, window, requester, flags, firsttag, ...)

      ULONG SetSGAttrs(struct @{"Gadget" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 215} *, struct @{"Window" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 797} *,
                       struct @{"Requester" Link "TEXT_INCLUDE:intuition/intuition.h/Main" 145} *, ULONG, Tag, ...);

@{b}   FUNCTION@{ub}
      Changes the attributes of a gadget modified by @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"},
      according to the attributes chosen in the tag list. If an attribute
      is not provided in the tag list, its value remains unchanged.

      This function is only able to change the attributes which are
      specific to "selectgclass", as well as the GA_Image attribute.
      Any other standard "gadgetclass" attribute is not recognized, so
      do NOT pass such attributes to SetSGAttrsA().

      The gadget will refresh its imagery to reflect changes to visual
      attributes, such as the active item, the "pop-up" symbol or the
      gadget's frame image. If you also want to change standard gadget
      attributes (like position, size and gadget text), first change them
      by hand in the gadget structure, then call this function with the
      tag item { SGA_Refresh, TRUE }, which will force a refresh.
      See the documentation of @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"} for a list of the fields
      in the gadget structure that you are allowed to change by hand.

      This function is provided to let you change the special attributes of
      non-BOOPSI gadgets that were initialized by InitSelectGadgetA(); you
      may not call @{"intuition.library/SetGadgetAttrsA()" Link "intuition/SetGadgetAttrsA()"} on this special kind
      of gadgets. The opposite is also true: this function must not be used
      with real BOOPSI gadgets (not even "selectgclass" ones).

@{b}   INPUTS@{ub}
      gadget - pointer to a custom gadget initialized by @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}.
               It may be NULL, in which case this function does nothing
      window - pointer to the window containing the gadget. It may be NULL,
               in which case the internal attributes of the gadget are
               altered but no rendering occurs
      requester - pointer to the requester containing the gadget, required
                  only for REQGADGETs
      flags - reserved for future use; please set this to zero for now
      taglist - array of @{"TagItem" Link "TEXT_INCLUDE:utility/tagitem.h/Main" 31} structures with attribute/value pairs

@{b}   TAGS@{ub}
      For the full list of "selectgclass" attributes, see the class reference
      documentation in the @{"--background--" Link "--background--"} paragraph, and only consider the
      attributes with the "S" applicability flag.

@{b}   RESULT@{ub}
      result - TRUE if all went ok, or FALSE if there was an error (usually
               a failure in some memory allocation)

@{b}   NOTES@{ub}
      Never, ever call this function with real "selectgclass" BOOPSI gadgets;
      use @{"intuition.library/SetGadgetAttrsA()" Link "intuition/SetGadgetAttrsA()"} instead.

@{b}   BUGS@{ub}
      None known.

@{b}   SEE ALSO@{ub}
      @{"InitSelectGadgetA()" Link "InitSelectGadgetA()"}, @{"ClearSelectGadget()" Link "ClearSelectGadget()"}, @{"GetSGAttr()" Link "GetSGAttr()"}

@EndNode

