@database "layout_gc"
@master "AMIDEV:NDK/Autodocs/layout_gc.doc"

@Node Main "layout_gc.doc"
@toc "Autodocs/AG/INDEX/Main"
    @{" --datasheet--() " Link "--datasheet--()"}
    @{" ActivateLayoutGadget() " Link "ActivateLayoutGadget()"}
    @{" FlushLayoutDomainCache() " Link "FlushLayoutDomainCache()"}
    @{" LAYOUT_GetClass() " Link "LAYOUT_GetClass()"}
    @{" LayoutLimits() " Link "LayoutLimits()"}
    @{" RethinkLayout() " Link "RethinkLayout()"}
    @{" --datasheet--() " Link "--datasheet--()"}
    @{" PAGE_GetClass() " Link "PAGE_GetClass()"}
    @{" RefreshPageGadget() " Link "RefreshPageGadget()"}
    @{" SetPageGadgetAttrsA() " Link "SetPageGadgetAttrsA()"}
@EndNode

@Node "--datasheet--()" "layout_gc/--datasheet--"

  NAME
      layout.gadget-- An automatic GUI layout arrangement gadget.

  SUPERCLASS
      gadgetclass

  DESCRIPTION
      The layout gadget is used to automatically calculate the
      positions and sizes of BOOPSI gadgets and images in a resizable
      window. Instead of handling the positions of gadgets by hand,
      you can just describe your window layout in a hierarchical
      fashion, and the layout gadget will do the rest.

@{b}   The basic method of layout of a group is as follows:@{ub}
@{b}   - Calculate the minimum and maximum size of each gadget.@{ub}
@{b}   - Calculate the weight totals for the group. Substract the size@{ub}
	 of the fixed size (weighted size 0) gadgets from the total
	 size of the group.
@{b}   - Distribute the remaining space in the group according to the@{ub}
	 relative weighs of the children.
@{b}   - If extra space remains, distribute it evenly between the@{ub}
	 children.

  METHODS
      GM_HANDLEINPUT -- Passed to the currently active child

      GM_HANDLESCROLL -- Passed to the child under the mouse

      GM_DOMAIN -- Passed to all children

      @{"GM_RENDER" Link "tabs_gc/GM_RENDER"} -- Passed to all children

@{b}   @{"GM_LAYOUT" Link "tabs_gc/GM_LAYOUT"} -- Passed to all children after first setting@{ub}
	   their size and position with SetAttrs. When invoked
	   by input.device, the stack is first swapped to provide
	   more workspace (this method is recursive).

@{b}   @{"GM_HITTEST" Link "tabs_gc/GM_HITTEST"} -- Passed to the child in whose domain@{ub}
	   rectangle the pointer is

@{b}   GM_HELPTEST -- Passed to the child in whose domain@{ub}
	   rectangle the pointer is

@{b}   @{"GM_GOACTIVE" Link "tabs_gc/GM_GOACTIVE"} -- Passed to the currently "active" child (one@{ub}
	   that returned GM_HITTEST)

@{b}   GM_GOINACTIVE -- Passed to the currently active child@{ub}

@{b}   @{"OM_SET" Link "tabs_gc/OM_SET"} -- Passed to superclass after scanning the@{ub}
	   taglist for layout specific tags

@{b}   OM_UPDATE -- Passed to superclass after scanning the@{ub}
	   taglist for layout specific tags

@{b}   @{"OM_GET" Link "tabs_gc/OM_GET"} -- Passed to superclass for non-layout tags@{ub}

@{b}   @{"OM_NEW" Link "tabs_gc/OM_NEW"} -- Passed to superclass, then adding all the@{ub}
	   children on the taglist to the private list.

@{b}   OM_DISPOSE -- Passed to all children (thus disposing all@{ub}
	   of them), then to superclass.

@{b}   GM_CLIPRECT -- Passed to all children.@{ub}

@{b}   DTM_PROCLAYOUT -- Like @{"GM_LAYOUT" Link "tabs_gc/GM_LAYOUT"}, but passes DTM_PROCLAYOUT@{ub}
	   forward. Useful if the layout group contains only
	   datatype objects.

@{b}   All other methods are passed to the superclass.@{ub}

  ATTRIBUTES
      Attributes global to the whole layout group. Pass all of these
      BEFORE adding child objects:

@{b}   GA_TextAttr (struct @{"TextAttr" Link "INCLUDE:graphics/text.h/Main" 63} *)@{ub}
	   The font that will be used for the group label.

	   Defaults to @{"NULL" Link "rexxsupport/NULL"} (RastPort default font).

	   Applicability is (OM_NEW)

      GA_ReadOnly (BOOL)
          Sets the layout object to readonly, input is ignored and blocked
          from reaching all children.

          Applicability is (OM_NEW, OM_SET)

      GA_Disabled (BOOL)
          Sets the layout object to disabled state. This tag is propagated
          down to all children.

          Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_Orientation (ULONG)@{ub}
	   Whether the objects of this group are arranged horizontally or
	   vertically. Possible values are LORIENT_HORIZONTAL and
	   LORIENT_VERTICAL.

	   Defaults to LORIENT_HORIZONTAL.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_FixedHoriz (BOOL)@{ub}
	   Whether the width of this layout group is fixed to the width
	   assigned by the window or parent layout group. If set to FALSE,
	   the gadget will minimize its width to the smallest possible
	   value. Generally you will have to also set LAYOUT_ShrinkWrap
	   (below) to TRUE also. It is recommended that this tag is used
	   only in the top layout group. Using a weighted width of 0 gives
	   more predictable results elsewhere.

	   Defaults to TRUE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_FixedVert (BOOL)@{ub}
	   Whether the height of this layout group is fixed to the height
	   assigned by the window or parent layout group. If set to FALSE,
	   the gadget will minimize its height to the smallest possible
	   value. Generally you will have to also set LAYOUT_ShrinkWrap
	   (below) to TRUE also. It is recommended that this tag is used
	   only in the top layout group. Using a weighted height of 0 gives
	   more predictable results elsewhere.

	   Defaults to TRUE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_HorizAlignment (ULONG)@{ub}
	   The horizontal alignment of the objects in this layout group.
	   Possible values are LALIGN_LEFT, LALIGN_RIGHT, and
	   LALIGN_CENTER.

	   Defaults to LALIGN_LEFT.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_VertAlignment (ULONG)@{ub}
	   The vertical alignment of the objects in this layout group.
	   Possible values are LALIGN_TOP, LALIGN_BOTTOM, and
	   LALIGN_CENTER.

	   Defaults to LALIGN_TOP.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_ShrinkWrap (BOOL)@{ub}
	   If set to TRUE, the layout group will shrink the interspacing
	   of the child objects to minimum. Normally all extra space (if
	   the total maximum size of the child objects is less than the
	   size of the layoutgroup) is evenly distributed between the
	   gadgets.

	   Defaults to FALSE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_EvenSize (BOOL)@{ub}
	   If TRUE, the layout group will try to reserve enough space to
	   make the minimum size of each child object equal to the minimum
	   of the largest child. Using this attribute makes it possible to
	   have neatly arranged horizontal rows or grids of gadgets. This
	   can take quite a bit of room, however, depending on the gadgets.

	   Defaults to FALSE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_SpaceInner (BOOL)@{ub}
	   Should layout leave space between objects or not. Set to FALSE
	   if objects in a group should be put immediately beside each
	   other.

	   Defaults to TRUE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_SpaceOuter (BOOL)@{ub}
	   Should layout leave space around the group's objects or not.
	   Set to TRUE if the objects should not be laid out using the
	   whole group container box (for example if the group has a
	   bevel around it).

	   Defaults to FALSE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_InnerSpacing (ULONG)@{ub}
	   The minimum space left between objects. The value is in "virtual
	   pixels", ie absolute pixels assuming bevel is configured for
	   thin lines. If bevel configuration is something else, the value
	   will be adjusted accordingly.

	   Please avoid using this tag, if you do not require absolute
	   control over the spacing. The LAYOUT_SpaceInner boolean is
	   provided to tell whether there should be spacing or whether
	   objects should be immediately connected to each other.

	   Defaults to INTERSPACING.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_TopSpacing@{ub}
@{b}   LAYOUT_BottomSpacing@{ub}
@{b}   LAYOUT_LeftSpacing@{ub}
@{b}   LAYOUT_RightSpacing (ULONG)@{ub}
	   The minimum space left to the top, bottom, left and right of
	   the group, respectively. This value is in "virtual pixels", see
	   LAYOUT_Spacing above.

	   Please avoid using this tag, if you do not require absolute
	   control over the spacing. The LAYOUT_SpaceOuter boolean is
	   provided to tell whether there should be spacing or whether
	   objects should be immediately connected to each other.

	   If you use one of these tags to override a LAYOUT_SpaceOuter,
	   pass this tag AFTER the LAYOUT_SpaceOuter tag.

	   Defaults to 0.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_BevelStyle (ULONG)@{ub}
	   The style of the bevel drawn around the group. This value is
	   passed to bevel.image.

	   Defaults to BVS_NONE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_BevelState (ULONG)@{ub}
	   The state of the bevel drawn around the group. Used to
	   @{"DrawImageState()" Link "intuition/DrawImageState()"} the bevel.image.

	   Defaults to IDS_NORMAL.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   LAYOUT_Label (STRPTR)@{ub}
	   The label drawn in the group bevel. This value is passed to
	   bevel.image. Note that if LAYOUT_BevelStyle is set to BVS_NONE,
	   no bevel will be rendered, and thus this label will not be used
	   either.

	   No default (bevel.image default used)

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_LabelImage (Object *)@{ub}
	   The BOOPSI image to use as the group bevel label. Passed to
	   bevel.image.

	   See LAYOUT_Label.

	   NOTE: bevel.image does not yet implement this feature so
	   this tag currently does nothing.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_LabelPlace (ULONG)@{ub}
	   The position of the label (See LAYOUT_Label).

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE, OM_GET)

@{b}   LAYOUT_RemoveChild (Object *)@{ub}
	   Pointer to an object you wish to remove from the layout
	   hierarchy. The object will be disposed of, so after using this
	   tag, the pointer will be invalid.

	   Applicability is (OM_SET)

@{b}   LAYOUT_AddChild (Object *)@{ub}
	   Pointer to an object you wish to add to the list of gadgets for
	   this layout hierarchy level.

	   @{"OM_SET" Link "tabs_gc/OM_SET"} was not supported at all until V47.
	   NOTE: If using @{"OM_SET" Link "tabs_gc/OM_SET"}, you *MUST* call through SetGadgetAttrs()
	   to protect the window layout properly.
			   (On OS4, you should use the LM_ADDCHILD method instead.)

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_AddImage (Object *)@{ub}
	   Same as LAYOUT_AddChild, but will mark the object as an
	   imageclass subclass (meaning that IM_DRAW will be used instead
	   of @{"GM_RENDER" Link "tabs_gc/GM_RENDER"} to display it, and that none of the gadgetclass
	   methods apply to it).

	   @{"OM_SET" Link "tabs_gc/OM_SET"} was not supported at all until V47.
	   NOTE: If using @{"OM_SET" Link "tabs_gc/OM_SET"}, you *MUST* call through SetGadgetAttrs()
	   to protect the window layout properly.
			   (On OS4, you should use the LM_ADDIMAGE method instead.)

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_ModifyChild (Object *)@{ub}
	   Inform layout gadget that the following child specific tags in
	   the taglist apply to the specified object. LAYOUT_AddChild will
	   do this automatically for new objects.

	   NOTE: You *MUST* call through SetGadgetAttrs() to protect the
	   window layout properly.

	   Applicability is (OM_SET)

@{b}   LAYOUT_RelVerify (BOOL)@{ub}
	   When a gadget returns a code that normally makes Intuition send
	   an IDCMP_GADGETUP message to the application, layout.gadget
	   will send a notification message (OM_NOTIFY, IDCMP_IDCMPUPDATE)
	   with the essential information of the gadgetup message. This is
	   because in certain situations the IDCMP_GADGETUP message can
	   not be sent (in particular, when tab cycling between gadgets).
	   The notification will consist of GA_ID set to the ID of the
	   gadget in question, this LAYOUT_RelVerify tag set to TRUE, and
	   the LAYOUT_RelCode tag (below) set to the gadget's return code
	   (IntuiMessage.Code field of the IDCMP_GADGETUP).

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_RelCode (UWORD)@{ub}
	   A copy of the IntuiMessage.Code field of the IDCMP_GADGETUP in
	   question, sent via OM_NOTIFY (ie. received as OM_UPDATE or
	   IDCMP_IDCMPUPDATE).

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_TabVerify (BOOL)@{ub}
	   If the gadget release was triggered by tab cycling, this
	   attribute will be TRUE in the release verify IDCMPUPDATE. This
	   lets you distinguish, for example, between pressing tab and
	   enter in a string gadget.

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_RelAddress (struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *)@{ub}
	   Address of the gadget that sent the gadgetup is provided in the
	   gadgetup notification using this tag.

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_Parent (Object *)@{ub}
	   Set automatically by layout.gadget for all child objects, this
	   attribute points to the parent layout object. If @{"NULL" Link "rexxsupport/NULL"}, the
	   layout object is the window's topmost layout.
	   When an object is added to the layout hierarchy, it will
	   receive this tag in @{"OM_SET" Link "tabs_gc/OM_SET"}. If you so wish, you may use this to
	   let the gadget talk to its parent layout group.
	   Any group gadget that should work with layout.gadget must
	   support this attribute.

	   Applicability is (OM_SET, OM_GET)

@{b}   LAYOUT_DeferLayout (BOOL)@{ub}
	   By setting this tag to TRUE in your window's top layout, you
	   can defer the layout and refresh process off the input.device
	   context to your application. This will make input.device more
	   responsive, and drop the (possibly quite heavy) process of
	   recalculating the display to normal application priority
	   instead of the priority 20
	   of input.device. @{"Input" Link "dos/Input()"} handling will be retained in input.device
	   context, to keep the GUI responsive.
	   If you use this tag, you must listen to LAYOUT_RequestLayout
	   and LAYOUT_RequestRefresh notifications and process them in
	   prompt manner, or your GUI will not display properly, if at all.

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_RequestLayout (Object *)@{ub}
	   If the above LAYOUT_DeferLayout tag is set to TRUE, the gadget
	   will defer @{"GM_LAYOUT" Link "tabs_gc/GM_LAYOUT"} methods invoked by input.device and notify
	   its IC target with this tag. You should be listening to it in
	   your application IDCMP handler (IDCMP_IDCMPUPDATE) and calling
	   @{"RethinkLayout" Link "layout_gc/RethinkLayout()"} with FALSE for refresh flag when receiving one.

	   Defaults to FALSE.

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_RequestRefresh (Object *)@{ub}
	   If the above LAYOUT_DeferLayout tag is set to TRUE, the gadget
	   will defer @{"GM_RENDER" Link "tabs_gc/GM_RENDER"} methods invoked by input.device and notify
	   its IC target with this tag. You should be listening to it in
	   your application IDCMP handler (IDCMP_IDCMPUPDATE) and calling
	   @{"RefreshGList" Link "intuition/RefreshGList()"} when receiving one.

	   Defaults to FALSE.

	   Applicability is (OM_NOTIFY)

@{b}   LAYOUT_TextPen (WORD)@{ub}
	   The pen that will be used for group label text. See bevel.image.

	   Applicability is (OM_NEW)

@{b}   LAYOUT_FillPen (WORD)@{ub}
	   The pen that will be used for the group fill pattern. See
	   bevel.image.

	   Applicability is (OM_NEW)

@{b}   LAYOUT_FillPattern (UWORD *)@{ub}
	   The fill pattern for the group. See bevel.image.

	   Defaults to none.

	   Applicability is (OM_NEW)

@{b}   GA_BackFill (struct @{"Hook" Link "INCLUDE:utility/hooks.h/Main" 26} *) (V44)@{ub}
@{b}   CLASSACT_BackFill (struct @{"Hook" Link "INCLUDE:utility/hooks.h/Main" 26} *)@{ub}
	   A layer backfill hook to use in the group to provide a more
	   complex background pattern.

	   Defaults to clear for the main layout, and none for sublayouts.

	   Applicability is (OM_NEW)

@{b}   LAYOUT_LabelColumn (ULONG)@{ub}
	   On which side of the gadget the label will be placed in the
	   group. Valid values are PLACETEXT_LEFT and PLACETEXT_RIGHT.
	   See CHILD_Label.

	   Defaults to PLACETEXT_LEFT.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_NOTIFY)

@{b}   LAYOUT_LabelWidth (ULONG)@{ub}
	   The width of the label column in a vertical group. This attribute
	   may be used to justify several layout groups.

	   Applicability is (OM_SET, OM_GET)

@{b}   LAYOUT_AlignLabels (Object *)@{ub}
	   A pointer to another layout instance that should have equal
	   label width with this one. Set to a cycle between all the
	   groups, these will automatically justify their labels with each
	   other. This attribute should be set as soon as possible, ie. in
	   @{"OM_NEW" Link "tabs_gc/OM_NEW"} or @{"OM_SET" Link "tabs_gc/OM_SET"} directly afterwards, before the layout size is
	   calculated.

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_Inverted (BOOL) (V42.27)@{ub}
	   Causes children to be added to the layout group via
	   @{"AddHead()" Link "exec/AddHead()"} vs @{"AddTail()" Link "exec/AddTail()"}.

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_WeightBar (BOOL) (V43.1)@{ub}
	   Place a user adjustable weighting bar here
	   (ie. balance group bar).

	   Applicability is (OM_NEW, OM_SET)

@{b}   LAYOUT_NoLayout (BOOL) (V45)@{ub}
	   Do not layout the children. All children must have valid
	   coordinates. Cannot be used with weight bars.

	   Defaults to FALSE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_GET)


@{b}   Attributes referring to the "current" child object:@{ub}

@{b}   CHILD_MinWidth, CHILD_MinHeight (ULONG)@{ub}
	   The minimum width and height of the object, in pixels. Setting
	   this attribute means that GM_DOMAIN is not respected in that
	   direction.

	   Defaults to ~0, which means that the layout gadget will ask the
	   object, using GM_DOMAIN.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   CHILD_MaxWidth, CHILD_MaxHeight (ULONG)@{ub}
	   As above, for the maximum size.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   CHILD_NominalSize (BOOL)@{ub}
	   If this attribute is TRUE, layout will use GDOMAIN_NOMINAL
	   instead of GDOMAIN_MINIMUM when requesting the minimum size of
	   the gadget. This is useful when the minimum size of a gadget
	   looks unattractive, but the gadget will return a more attractive
	   size with GDOMAIN_NOMINAL.

	   Defaults to FALSE.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   CHILD_WeightedWidth (ULONG)@{ub}
	   The relative width of the child object. See the DESCRIPTION
	   above for the layout method. If set to 0, the child will always
	   be rendered in the minimum size (specified by either GM_DOMAIN
	   or CHILD_MinWidth). Use CHILD_MinWidth and a weighted with of 0
	   instead of CHILD_MinWidth and CHILD_MaxWidth. The latter method
	   will also work, but will slow down the layout. As a special
	   rule, many BOOPSI images using bitmap data can not be resized
	   from the initial size. Fix their size by setting MinWidth and
	   MinHeight, and the weight to 0.

	   Defaults to 100.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   CHILD_WeightedHeight (ULONG)@{ub}
	   The relative height of the child object. See CHILD_WeightedWidth.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   CHILD_WeightMinimum (BOOL)@{ub}
	   Setting this tag to TRUE will make the layout group set the
	   weighted width and height to the minimum values set with
	   CHILD_MinWidth and CHILD_MinHeight or returned by GM_DOMAIN. This
	   allows creating layout groups where the relative size of the
	   objects always remains the same. Be warned that if the object
	   does not support GM_DOMAIN and minimum size is not set manually,
	   the weight will be set to 2 (the default minimum size of an
	   object). Normally you would want to set this tag for every
	   resizable object in a layout group.

	   Defaults to FALSE.

	   Applicability is (OM_NEW)

@{b}   CHILD_ReplaceObject@{ub}
@{b}   CHILD_ReplaceImage (Object *)@{ub}
	   Replace the current child object with the one specified. The
	   current object will be disposed of. See LAYOUT_AddChild,
	   LAYOUT_AddImage, LAYOUT_RemoveChild, LAYOUT_ModifyChild.

	   Applicability is (OM_SET)

	   NOTE: You *MUST* call through SetGadgetAttrs() to protect the
	   window layout properly.

@{b}   CHILD_CacheDomain (BOOL)@{ub}
	   To speed up resizing, layout gadget will normally cache the
	   first values returned by GM_DOMAIN and use that cache for
	   subsequent relayouts, instead of calling GM_DOMAIN again.
	   Normally this will have the same results all the time. If you
	   have a custom gadget that might return varying values between
	   calls to GM_DOMAIN (ie the minimum or maximum size of it could
	   vary during runtime), set this tag to FALSE for that object and
	   all its parent groups. Note that since layout groups are aware
	   of their parent layouts, they can disable caching in the
	   hierarchy above them automatically,  if you SetAttr this
	   attribute _AFTER_ creating the whole layout hierarchy.

	   Defaults to TRUE.

	   Applicability is (OM_NEW, OM_SET) (OM_SET preferred)

@{b}   CHILD_Label (Object *)@{ub}
	   The imageclass object, preferably label.image, to use as the
	   object's label. These labels are supported only in left or right
	   aligned groups, and will be placed at the left or right of the
	   gadget even in horizontal groups. All the labels will take the
	   space of the widest label. Label-less objects will be laid out
	   in full width; if you want to leave the label column empty, use
	   the special value LCLABEL_NOLABEL. Every object in a group gets
	   the same amount of space reserved for a label, whether they have
	   a label or not. This also (or in particular) applies to
	   horizontal groups; usually the correct effect is reached by
	   putting the label on the group itself instead of one of the
	   objects in it. See LAYOUT_LabelColumn.

	   Defaults to @{"NULL" Link "rexxsupport/NULL"}.

	   Applicability is (OM_NEW, OM_SET)

@{b}   CHILD_NoDispose (BOOL)@{ub}
	   By setting this attribute, you inform the layout object that
	   this child object should not be automatically disposed when
	   the layout object itself is disposed. This attribute allows
	   sharing objects between layouts.

	   Default is FALSE.

	   Applicability is (OM_NEW, OM_SET)

  NOTES
      Setting the attributes via SetGadgetAttrs() (OM_SET) will not
      automatically rerender the display! Call @{"RethinkLayout()" Link "RethinkLayout()"} to
      relayout and refresh display after SetGadgetAttrs().

@{b}   In this document, the terms layout, group, and object are used@{ub}
@{b}   intermixed. Most of the time, layout and group are used as@{ub}
@{b}   synonyms. Virtually any object referred to could also be a@{ub}
@{b}   layout group.@{ub}

@{b}   To make defining layout hierarchies easier, the classact.h@{ub}
@{b}   include file defines a set of macros that hide NewObject()@{ub}
@{b}   calls. This will clean up the rather large tag lists for the@{ub}
@{b}   creation of layout groups. See the ClassAct examples for use of@{ub}
@{b}   these macros, and layout.gadget in general.@{ub}

@{b}   In relation to above, remember that in AmigaOS (as of V40), the@{ub}
@{b}   stack size is restricted. During the beta test period, the@{ub}
@{b}   average size of a layout group for a whole window seemed to@{ub}
@{b}   average at approximately 1 KB. Building as large tag lists as@{ub}
@{b}   this on stack is rather slow, as well as easily overflowing the@{ub}
@{b}   small default stacks of AmigaOS. For windows with relatively@{ub}
@{b}   static layouts that are opened often, consider building tag@{ub}
@{b}   lists as static data and passing a pointer to them for@{ub}
@{b}   NewObjectA(). If this is too much work, make sure that your@{ub}
@{b}   program's stack is large enough to hold  the tag list. If it is@{ub}
@{b}   too small, you can use the V37 Exec @{"StackSwap()" Link "exec/StackSwap()"} call to replace@{ub}
@{b}   it with a larger one, or simply set the global variable long@{ub}
   __stack to a large enough value, if the startup code you link
@{b}   with provides stack swap support, as for example the c.o of@{ub}
@{b}   SAS/C 5.x and above does.@{ub}

@{b}   Due to Intuition limitations, IDCMP_GADGETUP messages are not@{ub}
@{b}   fully supported. The IAddress will always point to the root@{ub}
@{b}   layout object of the window, not the actual gadget the message@{ub}
@{b}   originates from. Use GadgetID to distinguish between gadgets.@{ub}
@{b}   When using tab cycle, GADGETUP messages will be lost@{ub}
@{b}   altogether. However, layout.gadget sends a notification for all@{ub}
@{b}   gadgetups, containing the tags GA_ID, LAYOUT_RelVerify and@{ub}
@{b}   LAYOUT_RelCode, containing, respectively, the ID, TRUE, and the@{ub}
@{b}   IntuiMessage.Code value it returned. Additionally a@{ub}
@{b}   LAYOUT_TabVerify tag will be TRUE or FALSE depending on whether@{ub}
@{b}   the gadget release was triggered by tab cycle.@{ub}
@{b}   Use of models and/or IDCMP_IDCMPUPDATE is encouraged.@{ub}

  SEE ALSO
      ClassAct example source for usage, and window_cl.doc

@EndNode

@Node "ActivateLayoutGadget()" "layout_gc/ActivateLayoutGadget"

  NAME
      ActivateLayoutGadget -- Activate a gadget within a layout window.

  SYNOPSIS
      Success = ActivateLayoutGadget( @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212}, @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942}, @{"Request" Link "intuition/Request()"}, @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} )
      d0							  a0	  a1	  a2	   d0

@{b}   @{"BOOL" Link "INCLUDE:exec/types.h/Main" 168} ActivateLayoutGadget( struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, struct @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} *,@{ub}
		   struct @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} *, ULONG );

  FUNCTION
      The equivalent of intuition.library @{"ActivateGadget()" Link "intuition/ActivateGadget()"} for a
      window controlled by layout.gadget. If successful, this means
      that the user does not need to click in the gadget before
      typing.

@{b}   The gadget parameter must point to the root layout gadget in@{ub}
@{b}   the window, and the object parameter to the gagdet you wish to@{ub}
@{b}   activate. This works by calling the private@{ub}
@{b}   LAYOUT_ACTIVATEOBJECT method to search the layout hierarchy for@{ub}
@{b}   the specified gadget, and set the handleinput path to that@{ub}
@{b}   gadget, and finally calling @{"ActivateGadget" Link "intuition/ActivateGadget()"} for the root object.@{ub}

@{b}   The rules of calling @{"ActivateGadget()" Link "intuition/ActivateGadget()"} apply to@{ub}
@{b}   ActivateLayoutGadget() also.@{ub}

  INPUTS
      @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} = pointer to the root layout obejct for the window.
      @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} = pointer to the window the gadget is in.
      @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} = pointer to a requester (may be NULL)
      @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} = pointer to the BOOPSI object you wish to activate.

  RESULT
      If the conditions above (and those of @{"ActivateGadget()" Link "intuition/ActivateGadget()"}) are
      met, the function will return TRUE, else FALSE.

  NOTES
      Not only string gadgets can be activated this way. Many
      ClassAct gadget classes, such as the button.gadget, also
      support keyboard control, and thus may be activated this way.

@{b}   An attempt to activate a gadget that is not currently visible@{ub}
   (as on a hidden page) will fail.

  SEE ALSO
      @{"intuition.library/ActivateGadget()" Link "intuition/ActivateGadget()"}

@EndNode

@Node "FlushLayoutDomainCache()" "layout_gc/FlushLayoutDomainCache"

  NAME
      FlushLayoutDomainCache -- @{"Flush" Link "dos/Flush()"} layout domain cache below a level.

  SYNOPSIS
      FlushLayoutDomainCache( layout )
                              a0

      void FlushLayoutDomainCache( struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} * )

  FUNCTION
      Layout gadget normally caches GM_DOMAIN results from the child
      objects to speed up window relayouts. However, on some rare
      occassions a gadget's minimum or maximum domain might change
      after creation. For these instances layout gadget provides two
      methods ontrolling the domain cache. You can set a caching on a
      child-by-child basis, using the CHILD_CacheDomain attribute, so
      that on each relayout the domain is calculated again. This
      method might have an extra performance hit, if the domain
      changes infrequently. It also has to be set for each parent
      layout level, which makes the amount of extra calculations grow
      quickly. The other method, for the cases where the application
      will know when a gadget's domain changes, is to call
      FlushLayoutDomainCache() with a pointer to the window's topmost
      layout object. This call will flush the whole hierarchy, so
      that the next window relayout will calculate all domains again.

  INPUTS
      layout = the layout object to flush. This should be the topmost
                  layout object for the window.

  SEE ALSO
      @{"--datasheet--" Link "window_cl/--datasheet--()"} (CHILD_CacheDomain attribute)

@EndNode

@Node "LAYOUT_GetClass()" "layout_gc/LAYOUT_GetClass"

  NAME
      LAYOUT_GetClass -- Gets the pointer to the layout class.

  SYNOPSIS
      layout_class = LAYOUT_GetClass();
      D0

      Class * LAYOUT_GetClass(VOID);

  FUNCTION
      Obtains the pointer to the layout gadget class for use with
      @{"NewObject()" Link "intuition/NewObject()"}.  This function always returns a valid pointer so
      you do not need to check it.  The reason is that if the library
      opens fine, then the pointer returned is already setup.  (Of
      course this implies that if opening the library fails, you
      shouldn't be calling this.)

@{b}   Note that this function does not create the class, that is done@{ub}
@{b}   when the class library is opened.@{ub}

  INPUTS
      Nothing.

  RESULT
      LayoutClass - Pointer to the layout gadget class.

@EndNode

@Node "LayoutLimits()" "layout_gc/LayoutLimits"

  NAME
      LayoutLimits -- easy way to find out max and min size of layout

  SYNOPSIS
      LayoutLimits( layout, limits, font, screen );
                    a0	  a1	  a2	a3

@{b}   void LayoutLimits( struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, struct LayoutLimits *,@{ub}
						   struct @{"TextFont" Link "INCLUDE:graphics/text.h/Main" 87} *, struct @{"Screen" Link "INCLUDE:intuition/screens.h/Main" 139} * )

  FUNCTION
      This function is an easy way of getting the minimum and maximum
      limit of the layout group. Effectively it create a @{"RastPort" Link "INCLUDE:graphics/rastport.h/Main" 52} and
      execute the GM_DOMAIN method for both minimum and maximum size
      of the object filling in the LayoutLimits structure with the size
      values. The font passed to this call will most likely affect the
      results, so use the font you will use with the window. If you
      pass a @{"NULL" Link "rexxsupport/NULL"} for the font, the system default font (monospaced)
      will be used. If you pass the optional screen pointer, the
      gadget will be provided a @{"DrawInfo" Link "INCLUDE:intuition/screens.h/Main" 66}. This will let the gadget
      adjust to the aspect ratio of the screen.

@{b}   If you use the resulting size for @{"OpenWindow()" Link "intuition/OpenWindow()"} or @{"WindowLimits()" Link "intuition/WindowLimits()"},@{ub}
@{b}   remember that the results do not include window borders.@{ub}

  INPUTS
      layout = the layout object to get the size on.
      limits = a pointer to the struct LayoutLimits to fill.
      font = the @{"TextFont" Link "INCLUDE:graphics/text.h/Main" 87} to use on the domain requests. May be @{"NULL" Link "rexxsupport/NULL"}
              for system default font.
      screen = optional pointer to the screen on which the layout
              will be used on, or @{"NULL" Link "rexxsupport/NULL"}.

  NOTES
      This function will invoke the object's GM_DOMAIN method twice,
      with a @{"NULL" Link "rexxsupport/NULL"} @{"GadgetInfo" Link "INCLUDE:intuition/cghooks.h/Main" 23}. If you call it providing a screen
      pointer, the taglist of the message will contain that screen's
      @{"DrawInfo" Link "INCLUDE:intuition/screens.h/Main" 66} (GA_DrawInfo) for aspect information.

  SEE ALSO
      gadgetclass/GM_DOMAIN

@EndNode

@Node "RethinkLayout()" "layout_gc/RethinkLayout"

  NAME
      RethinkLayout -- Relayout and render the layout. (V39)

  SYNOPSIS
      RethinkLayout( layout, window, requester, refresh );
                      a0		a1		a2

@{b}   void RethinkLayout( struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, struct @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} *,@{ub}
						   struct @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} *, @{"BOOL" Link "INCLUDE:exec/types.h/Main" 168} )

  FUNCTION
      Relayout and refresh the layout page. Call this function after
      a call SetGadgetAttrs() returns 1 to display the changes in the
      layout.  According to BOOPSI rules, a gadget will return a value
      equal or greater than 1 from @{"OM_SET" Link "tabs_gc/OM_SET"} to tell the application to refresh.
      This is what this function is for. Basically, it will call the
      @{"GM_LAYOUT" Link "tabs_gc/GM_LAYOUT"} and @{"GM_RENDER" Link "tabs_gc/GM_RENDER"} methods of the layout.

  INPUTS
      layout = the layout to refresh. Doesn't have to be the topmost
                  object in the hierarchy, if the changes do not affect
                  it.
      window = the window to which the layout (or its parent) is
                  attached to.
      requester = the window's requester, or @{"NULL" Link "rexxsupport/NULL"}.
      refresh = whether layout.gadget should also refresh the display.

  NOTES
      This function emulates a DoGadgetMethod() on V37 and V38 systems.

@{b}   The refresh flag is provided for several reasons. First, when using@{ub}
@{b}   LAYOUT_DeferLayout, you should not refresh upon receiving a@{ub}
@{b}   LAYOUT_RequestLayout notification. Second, datatypes have an@{ub}
@{b}   asynchronous layout, and should not be attempted to refresh before@{ub}
@{b}   that is finished. @{"Wait" Link "exec/Wait()"} for DTA_Sync, and then RefreshGList( layout,@{ub}
@{b}   window, requester, 1 ).@{ub}

  SEE ALSO
      @{"intuition.library/RefreshGList()" Link "intuition/RefreshGList()"}, @{"intuition.library/SetGadgetAttrsA()" Link "intuition/SetGadgetAttrsA()"},
      intuition.library/DoGadgetMethod()

@EndNode

@Node "--datasheet--()" "page_gc/--datasheet--"

  NAME
@{b}   page.gadget -- a gadget for easy creation of GUI pages.@{ub}

  SUPERCLASS
@{b}   gadgetclass@{ub}

  DESCRIPTION
@{b}   Page gadget takes a list of BOOPSI objects and treats each as a@{ub}
@{b}   single page of a multi-page GUI group. Used together with@{ub}
@{b}   tabs.gadget and layout.gadget, it allows complex GUI layouts with@{ub}
@{b}   hidden objects with virtually no work for the developer.@{ub}

@{b}   This gadget class is contained within the layout.gadget binary.@{ub}
@{b}   Thus, you will need to @{"OpenLibrary" Link "exec/OpenLibrary()"} layout.gadget, but not@{ub}
@{b}   page.gadget.@{ub}

  METHODS
@{b}   GM_DOMAIN@{ub}
@{b}   GM_RENDER@{ub}
@{b}   GM_LAYOUT@{ub}
@{b}   DTM_PROCLAYOUT@{ub}
@{b}   OM_SET@{ub}
@{b}   OM_UPDATE@{ub}
@{b}   OM_NEW@{ub}
@{b}   OM_DISPOSE@{ub}

@{b}   All other methods are passed to the currently visible object.@{ub}

  ATTRIBUTES
@{b}   PAGE_Add (Object *)@{ub}
	   A BOOPSI gadget (probably a layout.gadget) to add to the end of
	   the page list.

	   Applicability is (OM_NET, OM_SET)

@{b}   PAGE_Remove (Object *)@{ub}
	   Pointer to a gadget to remove from the page list. page.gadget
	   will automatically dispose all attached objects when disposed of.

	   Applicability is (OM_SET)

@{b}   PAGE_Current (ULONG)@{ub}
	   Sets/gets the currently visible page. Note that @{"OM_SET" Link "tabs_gc/OM_SET"} will NOT
	   trigger a rerender, call @{"RethinkLayout()" Link "RethinkLayout()"} afterwards. OM_UPDATE
	   will rerender automatically.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   PAGE_FixedVert, PAGE_FixedHoriz (BOOL)@{ub}
	   Like the respective tags of layout.gadget, these will, if set
	   to FALSE, force the group's dimensions to the smallest possible
	   in the respective direction.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

@{b}   PAGE_NoDispose (BOOL) v53.22 and V47@{ub}
	   Set the to True if you do not want the Objects to be Disposed.

	   Applicability is (OM_NEW, @{"OM_SET" Link "tabs_gc/OM_SET"}, OM_UPDATE)

  SEE ALSO
@{b}   layout.gadget/--datasheet--@{ub}
@{b}   ClassAct example source for usage.@{ub}

@EndNode

@Node "PAGE_GetClass()" "page_gc/PAGE_GetClass"

  NAME
@{b}   PAGE_GetClass -- Gets the pointer to the Page class.@{ub}

  SYNOPSIS
@{b}   page_class = PAGE_GetClass();@{ub}
   D0

@{b}   Class * PAGE_GetClass(VOID);@{ub}

  FUNCTION
@{b}   Obtains the pointer to the page gadget class for use with@{ub}
@{b}   @{"NewObject()" Link "intuition/NewObject()"}.  This function always returns a valid pointer so@{ub}
@{b}   you do not need to check it.  The reason is that if the library@{ub}
@{b}   opens fine, then the pointer returned is already setup.  (Of course@{ub}
@{b}   this implies that if opening the library fails, you shouldn't be@{ub}
@{b}   calling this.)@{ub}

@{b}   Note that this function does not create the class, that is done@{ub}
@{b}   when the class library is opened.@{ub}

  INPUTS
@{b}   Nothing.@{ub}

  NOTES
@{b}   PAGE_GetClass() is contained in layout.gadget. There is no PageBase,@{ub}
@{b}   just LayoutBase.@{ub}

  RESULT
@{b}   page_class - Pointer to the page gadget class.@{ub}

@EndNode

@Node "RefreshPageGadget()" "page_gc/RefreshPageGadget"

NAME
	RefreshPageGadget -- Refresh gadget in a paged layout

SYNOPSIS
	RefreshPageGadget(gad, page, win, req)
					  A0	 A1	   A2   A3

	void RefreshPageGadget(struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} *,
			struct @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} *, struct @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} *)

FUNCTION
	Performs a RefreshGList( gad, win, req, 1 ) if the gadget is on
	the currently visible page.

@EndNode

@Node "SetPageGadgetAttrsA()" "page_gc/SetPageGadgetAttrsA"

NAME
	SetPageGadgetAttrsA -- Set gadget attributes in a paged layout
	SetPageGadgetAttrs -- Varargs stub for SetPageGadgetAttrsA

SYNOPSIS
	value = SetPageGadgetAttrsA(gad, page, win, req, tags)
	D0							A0	 A1	   A2   A3   A4

	ULONG SetPageGadgetAttrsA(struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} *,
			struct @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} *, struct @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} *, struct @{"TagItem" Link "INCLUDE:utility/tagitem.h/Main" 30} *)

	ULONG SetPageGadgetAttrs(struct @{"Gadget" Link "INCLUDE:intuition/intuition.h/Main" 212} *, @{"Object" Link "INCLUDE:intuition/classusr.h/Main" 18} *,
			struct @{"Window" Link "INCLUDE:intuition/intuition.h/Main" 942} *, struct @{"Requester" Link "INCLUDE:intuition/intuition.h/Main" 142} *, ULONG, ...)

FUNCTION
	Like SetGadgetAttrs, but passes a @{"NULL" Link "rexxsupport/NULL"} window and requester pointer
	if the gadget is not on the currently visible page.

@EndNode

