<?xml version="1.0"?>
<!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.3//EN" "http://www.gnustep.org/gsdoc-1_0_3.dtd">
<gsdoc base="GSHbox" up="GuiAdditions">
  <head>
    <title>GSHbox</title>
    <author name="Nicola Pero">
      <email address="n.pero@mi.flashnet.it">
        n.pero@mi.flashnet.it
      </email>
    </author>
    <abstract>The GSHbox class (a GNU extension)</abstract>
    <copy>1999 Free Software Foundation, Inc.</copy>
  </head>
  <body>
    <front><contents /></front>
    <chapter>
      <heading>GSHbox</heading>
      <p>
        GSHbox inherits from GSTable the autosizing/autoresizing
        engine. The only real difference between a GSHbox and a
        GSTable with 1 row is that the GSHbox has a much
        simpler, easier and friendlier API.
      </p>
      <p>
        You shouldn't use GSTable methods with GSHbox (exception:
        methods explicitly quoted in comments to this file as
        'inherited from GSTable'). If you need to do that,
        you should be using GSTable instead.
      </p>
      <p>
        A GSHbox is an invisible view (a logical device) which can
        contain some views. The GSHbox controls the position
        and sizes of these views so that they are lined up in a
        row.
      </p>
      <p>
        To initialize a GSHbox, you should always use
        <ref type="method" id="-init">
          -init
        </ref>
        method. Don't use GSTable methods. The correct way to
        start using a new GSHbox is simply:
      </p>
<example>
  hbox = [GSHbox new];
  </example>
    <p>
      (well, of course, autoreleasing it if necessary). You add
      a view to a GSHbox using the method
      <ref type="method" id="-addView:">
        -addView:
      </ref>
      and its variants. The views you add to a GSHbox are placed by
      the GSHbox in its subview hierarchy, and moved (and/or
      resized in the vertical direction) so that they are
      positioned one after the other, from left to right, in
      a row. Before adding views to a box, you should resize them to
      the least comfortable size you want them to have. The GSHbox
      considers this size as the minimum size your view
      should ever have, and never resizes your view below this
      size.
    </p>
    <p>
      The initial size of the GSHbox is zero; each time you add a
      view in the GSHbox, the GSHbox resizes itself to fit the new
      contents. Usually, you simply add objects to the
      GSHbox, and let it compute its size (this is the minimum
      size); you may get this resulting size by
    </p>
<example>
  size = [yourHBox size];
  </example>
    <p>
      for example, if the GSHbox is to be used as the content view
      of a window, you may create the window exactly with this size.
    </p>
    <p>
      You should never force a GSHbox in a size different from the
      one it has automatically computed. It sounds quite pointless
      anyway. The only correct (and meaningful) way to resize a
      GSHbox is through
      <ref type="method" id="-resizeWithOldSuperviewSize:">
        -resizeWithOldSuperviewSize:
      </ref>
      messages (in the view hierarchy). In other words, after
      you place your box in the view hierarchy, then you may resize
      the superview and (if the superview has autoresizing of
      subviews enabled) your box is resized automatically
      accordingly.
    </p>
    <p>
      By default, there is no space between the added views. By
      using the method
      <ref type="method" id="-addView:withMinXMargin:">
        -addView:withMinXMargin:
      </ref>
      you may tell the GSHbox to insert some space (a
      <var>margin</var>) between the view you are adding and the
      previous one (the one at its left).
    </p>
    <p>
      If what you want is space around the GSHbox, and not between
      views in the GSHbox, you don't want a margin but a
      <var>border</var>; you should then use
      <ref type="method" id="-setBorder:">
        -setBorder:
      </ref>
      , which will add an equal amount of space on all the sides of
      the box. You can also set a different border on each side
      (see
      <ref type="method" id="-setMinXBorder:">
        -setMinXBorder:
      </ref>
      and similar methods).
    </p>
    <p>
      A useful feature of GSHbox is that it supports
      <var>separators</var>. This facility is not directly
      available in GSTable (to add separators to a GSTable
      you need to create and handle them yourself). A GSHbox
      separator is a vertical groove line, used to mark the
      separation between different elements of a box. To add
      a separator, simply invoke the method
      <ref type="method" id="-addSeparator">
        -addSeparator
      </ref>
      . The separator is put at the right of the last added view.
    </p>
    <p>
      To use GSHbox proficiently, it is crucial to set correctly the
      autoresizing mask of each view before adding it to
      the GSHbox.
    </p>
    <p>
      The GSHbox treats each view and its margins as a whole (see
      the GSTable class description for more information).
    </p>
    <p>
      When the GSHbox is resized in the vertical direction (as a
      consequence of user intervertion, for example), what
      happens is:
    </p>
    <list>
      <item>
        if the new height is less than the minimum height of the
        GSHbox (computed as the maximum of the minimum height of
        the added views), it simply resizes all the added views to
        this minimum height; part of them are clipped then.
      </item>
      <item>
        if the new height is greater than the GSHbox's minimum
        height, the GSHbox resizes all the added views to the
        new height. This is done through the standard
        superview-subview resizing mechanism, so
        that, by setting the autoresizingMask of each view that
        you add, you are able to control exactly how the resizing
        effects each view and its margins.
      </item>
    </list>
    <p>
      When the GSHbox is resized in the horizontal direction, its
      behaviour is as follows:
    </p>
    <list>
      <item>
        If the new width is less than the minimum width, all the
        added views are sized to minimum width; part of them is
        clipped then.
      </item>
      <item>
        If the new width is greater than the minimum width, some of
        the views are resized. You may decide which views you want
        to be resized and which not; to disable resizing of a
        certain view in the horizontal direction, you should
        specify a <code>NO</code> value to the option
        <code>enablingXResizing</code> when you add the view to
        the box. Views with X Resizing Not Enabled are always kept
        in their minimum width (the original one), and never
        resized. If nothing is specified, a default of
        <code>YES</code> for <code>enablingXResizing</code> is
        understood. So, when the new width is greater than
        the minimum width, the excess width is equally divided
        between the view with X Resizing Enabled. The actual
        resizing is done through the usual superview-subview
        resizing mechanism, so that again you may influence
        the way the resizing affects each view by setting the
        autoresizing mask of each view.
      </item>
    </list>
    <class name="GSHbox" super="GSTable" ovadd="1.0.0">
      <declared>GNUstepGUI/GSHbox.h</declared>
      <desc>
        <em>Description forthcoming.</em>
      </desc>
        <ivariable type="float" name="_defaultMinXMargin" validity="protected" ovadd="1.0.0">
          <desc>
            <em>Warning</em> the underscore at the start of the
            name of this instance variable indicates that, even
            though it is not technically <em>private</em>, it is
            intended for internal use within the package, and
            you should not use the variable in other code.
          </desc>
        </ivariable>
        <ivariable type="BOOL" name="_haveViews" validity="protected" ovadd="1.0.0">
          <desc>
            <em>Warning</em> the underscore at the start of the
            name of this instance variable indicates that, even
            though it is not technically <em>private</em>, it is
            intended for internal use within the package, and
            you should not use the variable in other code.
          </desc>
        </ivariable>
        <method type="void" ovadd="1.0.0">
          <sel>addSeparator</sel>
          <desc>
            Add a separator with the default MinXMargin.
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>addSeparatorWithMinXMargin:</sel>
          <arg type="float">aMargin</arg>
          <desc>
            Add a separator (a vertical groove line encompassing
            all the height of the GSHbox) to the GSHbox, inserting
            a margin <var>aMargin</var> between the separator and the
            last added view.
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>addView:</sel>
          <arg type="NSView*">aView</arg>
          <desc>
            See
            <ref type="method" id="-addView:enablingXResizing:withMinXMargin:">-addView:enablingXResizing:withMinXMargin:</ref>
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>addView:</sel>
          <arg type="NSView*">aView</arg>
          <sel>enablingXResizing:</sel>
          <arg type="BOOL">aFlag</arg>
          <desc>
            See
            <ref type="method" id="-addView:enablingXResizing:withMinXMargin:">-addView:enablingXResizing:withMinXMargin:</ref>
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>addView:</sel>
          <arg type="NSView*">aView</arg>
          <sel>enablingXResizing:</sel>
          <arg type="BOOL">aFlag</arg>
          <sel>withMinXMargin:</sel>
          <arg type="float">aMargin</arg>
          <desc>
            <p>
              Pack views in the GSHbox. Don't use the
              corresponding methods of GSTable, which are
              far more general and far more complicate. If you need
              to do that, use GSTable instead.
            </p>
            <p>
              Add a view to the box, enabling X Resizing only if
              flag is <code>YES</code>, and a MinXMargin
              <var>aMargin</var>. If <var>aFlag</var> is
              <code>YES</code> the [view and its margins] should
              be resized in the horizontal direction when the GSHbox
              is resized in the horizontal direction. If
              <var>aFlag</var> is <code>NO</code> the view is
              never X-resized and always left in its original
              width. The default is <code>YES</code>.
            </p>
            <p>
              The min X margin is used to separate the view from
              the preceding one. The first view added to the box
              has no min X margin; if you try setting one for it,
              it is ignored (zero is used instead).
            </p>
            <p>
              When views are added to the GSHbox, it might happen
              that some of the added views have a greater height
              than others. When this happens, the GSHbox resizes
              all the views to the highest height. As usual, each
              view is resized with its margins; the effect of the
              resizing on each view is determined by the
              autoresizing mask of the view. The classical
              options are
            </p>
            <deflist>
              <term>(NSViewMinYMargin | NSViewMaxYMargin)</term>
              <desc>Center the view vertically</desc>
              <term>NSViewMinYMargin</term>
              <desc>
                Flush the view up (down if the GSHbox is flipped)
              </desc>
              <term>NSViewMaxYMargin</term>
              <desc>
                Flush the view down (up if the GSHbox is flipped)
              </desc>
              <term>NSViewHeightSizable</term>
              <desc>Expand the view to the whole height</desc>
            </deflist>
            <p>
              (you may need to OR these masks with the mask you
              use in the horizontal direction, if you use any).
            </p>
            <p>
              With a GSHbox, only one margin is set when you add
              views to the GSHbox: the margin between each view
              and the preceding one. Exception: the first view is
              special, and has no margin set (it has no
              preceding view to be separated from). Space
              above or below the view may result if the view is
              shorter, in the vertical direction, than the
              other views in the GSHbox; in that case the view is
              resized to fit vertically, according to its
              autoresizingMask. By changing the
              autoresizingMask you may decide whether
              the space should go to the view or to its vertical
              margins; this for example lets you center
              vertically or flush up/down your view.
            </p>
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>addView:</sel>
          <arg type="NSView*">aView</arg>
          <sel>withMinXMargin:</sel>
          <arg type="float">aMargin</arg>
          <desc>
            See
            <ref type="method" id="-addView:enablingXResizing:withMinXMargin:">-addView:enablingXResizing:withMinXMargin:</ref>
          </desc>
        </method>
        <method type="id" ovadd="1.0.0">
          <sel>init</sel>
          <desc>
            Always use init for GSHbox: other methods don't make
            sense. Don't used GSTable methods. You do not need
            to specify the number of views you plan to put in the
            box when you initialize it.
          </desc>
        </method>
        <method type="int" ovadd="1.0.0">
          <sel>numberOfViews</sel>
          <desc>
            Return the number of views in the GSHbox (separators
            included).
          </desc>
        </method>
        <method type="void" ovadd="1.0.0">
          <sel>setDefaultMinXMargin:</sel>
          <arg type="float">aMargin</arg>
          <desc>
            Use only the following method to set a default margin.
            The default margin set with the following method will
            be used for all the views added after. (Exception: the
            first view put in the box has no margins at all) It
            will not affect already added views. In a GSHbox, only
            one margin is used, the one between each view and the
            preceding one. If what you want is space around
            the GSHbox, you don't want a margin but a border; use
            setBorder: (see GSTable, "Setting Border"). If
            you need more complicated margins/borders, use GSTable.
          </desc>
        </method>
    </class>
  </chapter>
  </body>
</gsdoc>
