PLINIT(2)                                               PLINIT(2)

     NAME
          Panel, Rtext, plpack, plmove, pldraw, plfree, plgrabkb,
          plkeyboard, plmouse, plscroll, plentryval, plsetbutton,
          plsetslider, pleget, plelen, plegetsel, plepaste, plesel,
          plescroll, plgetscroll, plsetscroll, plplacelabel, plrtstr,
          plrtbitmap, plrtpanel, plrtfree, plgetpostextview,
          plsetpostextview - Panel manipulation functions

     SYNOPSIS
          #include <u.h>
          #include <libg.h>
          #include <panel.h>

          int plinit(int ldepth)

          int plpack(Panel *p, Rectangle r)

          void plmove(Panel *p, Point loc)

          void pldraw(Panel *p, Bitmap *b)

          void plfree(Panel *p)

          void plgrabkb(Panel *p)

          void plkeyboard(Rune c)

          void plmouse(Panel *p, Mouse m)

          void plscroll(Panel *scrollee, Panel *xscroller, Panel *yscroller)

          char *plentryval(Panel *entry)

          void plsetbutton(Panel *button, int value)

          void plsetslider(Panel *slider, int value, int range)

          Rune *pleget(Panel *edit)

          int plelen(Panel *edit)

          void plegetsel(Panel *edit, int *start, int *end)

          void plepaste(Panel *edit, Rune *text, int ntext)

          void plesel(Panel *edit, int start, int end)

          void plescroll(Panel *edit, int index)

          Scroll plgetscroll(Panel *p)

     Page 1                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          void plsetscroll(Panel *p, Scroll s)

          void plplacelabel(Panel *p, int loc)

          Rtext *plrtstr(Rtext **head, int space, int indent,
                         Font *font, char *str, int hot, void *user)

          Rtext *plrtbitmap(Rtext **head, int space, int indent,
                            Bitmap *image, int hot, void *user)

          Rtext *plrtpanel(Rtext **head, int space, int indent,
                           Panel *panel, int hot, void *user)

          void plrtfree(Rtext *text)

          Rtext *plgetpostextview(Panel *view)

          void plsetpostextview(Panel *view, Rtext *text)

     DESCRIPTION
          The panel library assists in making simple graphical control
          panels for interactive applications.  As drawn on the
          screen, a panel is a collection of nested rectangles with
          things drawn in them, representing labels, buttons, editable
          text displays, scroll bars, and other user interface fea-
          tures.  Corresponding to the nest of boxes is a tree of
          Panel structures.  A node's children are drawn nested inside
          their parent.  The publicly visible part of a Panel struc-
          ture looks like this

               typedef struct Panel Panel;
               struct Panel{
                    Point ipad, pad; /* extra space inside and outside */
                    Point fixedsize; /* size of Panel, if FIXED */
                    int user;        /* available for user */
                    void *userp;     /* available for user */
                    Rectangle r;     /* where the Panel goes */
                    ...              /* more private fields follow */
               };

          Rectangle r is the box containing this Panel node and its
          children.  Its value is computed by plpack. The user and
          userp fields are not used by the panel library.  They are
          provided so that user code can attach data to a Panel node.
          The Points ipad, pad, and fixedsize may be set by user code
          and are examined by plpack.

          This manual page catalogs those panel library functions not
          directly concerned with creating or reinitializing Panel
          data structures.  See plbutton(2) and plinitbutton(2) for
          those.  The Panel library memo in Volume 2 of this manual
          contains a more detailed description of these functions,

     Page 2                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          illustrated with examples.

          The plinit function initializes panel library data struc-
          tures.  Its argument is the ldepth of the bitmaps on which
          panels will be drawn.  The panel library draws things dif-
          ferently on one-bit and multi-bit-per-pixel displays.

          There is usually no need to specify exact sizes and screen
          locations of Panel nodes.

          Screen layout is computed by plpack, whose arguments are a
          pointer to a Panel tree and a Rectangle in which the layout
          should fit.  Plpack returns 1 if it could fit everything
          into the rectangle, and 0 if it could not.  Briefly, plpack
          processes a Panel tree in two passes.  The first, bottom-up
          pass computes the amount of space required to house the
          children of each panel.  The second pass proceeds top-down
          and divides the space available to each panel among its
          children.  Every Panel has some minimum space requirement -
          for example, a button must be big enough to fit its label
          inside its border, and a group must be large enough to hold
          its children.  Space is allocated to a Panel's children in
          eldest to youngest order by slicing an appropriately sized
          piece off one of the four sides of the available rectangle.
          Each Panel has a flag word (specified when the Panel is cre-
          ated - see plbutton(2)), one of whose fields can have the
          value PACKN, PACKE, PACKS or PACKW (default PACKN), specify-
          ing from which side to cut the piece.  Other flags are:

          FILLX FILLY
               The rectangle that plpack slices off for a Panel may be
               larger than the Panel needs.  For example, if a small
               button with PACKW set is packed inside a large rectan-
               gle, plpack will slice off a piece that fits snugly in
               the x direction, but that will likely be too big in the
               y direction.  Specifying instead PACKW|FILLY will grow
               the button in the y direction to fill the extra space.

          PLACECEN PLACES PLACEE PLACEW PLACEN
          PLACENE PLACENW PLACESE PLACESW
               If a Panel is not expanded to fill the slack, these
               flags can specify where in the available space to place
               it.  The default is PLACECEN, which centers the panel
               in the space allocated for it.  The other PLACE flags
               place the Panel at one of the eight compass points.

          FIXED FIXEDX FIXEDY
               A user's code can override whatever size calculation
               plpack performs by setting the FIXED flag and storing a
               value in the Panel's fixedsize field.  FIXED is the
               conjunction of FIXEDX and FIXEDY, which fix a Panel's
               horizontal and vertical extent independently.

     Page 3                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          MAXX MAXY
               If either of these flags is set, the Panel's x or y
               size requirement is increased to be equal to that of
               its largest sibling.

          Once a Panel tree is packed, it can be moved to a different
          location by calling plmove, whose arguments are the panel to
          be moved and the upper left-hand corner of its destination.

          Pldraw displays its Panel argument in the given Bitmap.
          Since each Panel's children are drawn nested inside it, pro-
          grams can do partial screen updates by calling pldraw on
          interior nodes of a Panel tree.  For example, after calling
          plinitlabel to change the text of a label, calling pldraw on
          the label will redisplay it, without having to update the
          rest of the display.  An application that wishes to discard
          a Panel tree should pass it to plfree to release the stor-
          age.

          Three functions control how a Panel processes mouse and key-
          board input:

          plmouse     takes two arguments, a Panel pointer and a Mouse
                      structure as returned by emouse (see event(2)).
                      Plmouse determines which node of the Panel tree
                      should receive the mouse event and calls panel-
                      specific code to process the event.  That code
                      may in turn call back to user-supplied functions
                      to register button hits, slider movement, etc.
                      Hit routines are generally specified when
                      panel-creation functions are called.
          plgrabkb    takes one argument, a pointer to a Panel to
                      which keyboard input should be directed.  We say
                      that this panel ``has the keyboard focus.''
                      Passing a null pointer to plgrabkb causes subse-
                      quent keyboard input to be ignored.
          plkeyboard  takes one argument, a Rune, presumably obtained
                      from ekbd or its equivalent and sends it to the
                      panel that has the keyboard focus, if any.

          Programs that use scroll bars created with plscrollbar to
          control scrollable panels (currently pledit, pllist, and
          pltextview panels) must call plscroll to indicate to the
          panel library which scroll bar adjusts which panel.  Its
          arguments are three pointers to panels: the panel to be
          scrolled, the panel that scrolls it in the x direction, and
          the panel that scrolls it in the y direction.  Either of the
          latter two may be null, indicating no control in that direc-
          tion.  Currently no panel responds to scrolling in x; that
          option is for future expansion.

          The rest of the functions test or set values hidden in

     Page 4                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          certain Panel types or perform other miscellaneous manipula-
          tions such as saving and restoring scroll points.

          The plentryval entry returns a pointer to the string entered
          into a plentry panel (q.v.).  Its argument is the panel in
          question.

          Plsetbutton takes two arguments.  The first must point to a
          plcheckbutton or plradiobutton panel.  The function sets or
          clears the button's checkmark, depending on whether its sec-
          ond argument is 0 or 1.

          Plsetslider adjusts the position of the slider, its first
          argument.  The value argument gives the setting, in units
          such that the range argument gives full scale.  For example

               plsetslider(s, 50, 100);
               plsetslider(s, 1, 2);
               plsetslider(s, 17, 34);

          each set slider s to the 50% mark.

          The following functions all manipulate the editable text
          panels created by pledit. The first argument of each is a
          pointer to the edit panel.

          pleget     returns a pointer to an array of Runes containing
                     the edit window's text.
          plelen     returns the number of Runes in the text.
          plegetsel  stores in *start and *end the endpoints of the
                     edit window's current selection.
          plepaste   replaces the current selection with the text
                     pointed to by text, whose length is ntext Runes.
          plesel     sets the endpoints of the selection to start and
                     end.
          plescroll  scrolls the edit window so that the line contain-
                     ing the Rune with the given index is at the top
                     of the screen.

          The arguments of plplacelabel are a pointer to a pllabel
          panel and one of the flags PLACECEN, PLACES, PLACEE, PLACEW,
          PLACEN, PLACENE, PLACENW, PLACESE, or PLACESW.  This func-
          tion indicates where in the space allocated for the label
          the label's text should be drawn.  The text is centered by
          default.

          The argument of plgetscroll should point to a scrollable
          Panel.  The return value is a magic cookie (of type Scroll)
          that indicates where it is scrolled to.  When the panel
          pointer and the cookie are passed to plsetscroll, it will
          scroll the panel back to the place it was at when
          plgetscroll was called.  The magic cookie encodes the scroll

     Page 5                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          position on a percentage basis, so all bets are off if the
          contents of the panel are different at the calls to
          plgetscroll and plsetscroll.

          Plgetpostextview and plsetpostextview perform a similar
          function, but they only work on pltextview panels.  However,
          since plgetpostextview returns a pointer to the Rtext that
          is displayed in the upper left-hand corner of the panel and
          plsetpostextview scrolls the given Rtext back to the upper
          left-hand corner, the caveat mentioned above does not apply.

          Finally, there is a group of functions that create the Rtext
          lists that are displayed by pltextview panels.  Line breaks
          can occur only between the members of an Rtext list.  An
          individual Rtext structure describes a bitmap, or a string
          of text to be drawn in a single call to string (see
          bitblt(2)), or a Panel to be drawn inline.  The publicly
          visible parts of an Rtext look like this:

               typedef struct Rtext Rtext;
               struct Rtext{
                    int hot;     /* responds to hits? */
                    void *user;  /* user data */
                    int space;   /* how much space before, if no break */
                    int indent;  /* how much space before, after a break */
                    Bitmap *b;   /* what to display, if nonzero */
                    Panel *p;    /* what to display, if nonzero and b==0 */
                    Font *font;  /* font in which to draw text */
                    char *text;  /* what to display, if b==0 and p==0 */
                    Rtext *next; /* next piece */
                    ...          /* more private fields follow */
               };

          The fields are:

          hot     indicates whether or not this Rtext is sensitive to
                  mouse hits.
          user    points to user data not used by the panel library.
                  User code may use this pointer to annotate an Rtext.
          space   how much space to leave to the left of this Rtext if
                  it appears on the same line as the previous one.  To
                  allow the display of words with internal font
                  changes, if space is zero, there will never be a
                  line break between this Rtext and the previous one.
          indent  How much space to leave between this Rtext and the
                  left margin, if it is the first one on the line.
          b       a bitmap to be displayed, if non-null.
          p       a panel to be displayed, if non-null and b==0.
          font    the font in which text is to be drawn.
          text    the string to be displayed, if b==0 and p==0.
          next    the next Rtext on the list.

     Page 6                       Plan 9             (printed 4/25/24)

     PLINIT(2)                                               PLINIT(2)

          The functions plrtstr, plrtbitmap, and plrtpanel create
          nodes in an Rtext list, returning a pointer to the newly
          created node.  For all three functions, the space, indent,
          hot, and user arguments initialize the corresponding field
          of the Rtext, and head points to a pointer to the head of
          the list, which the functions will update appropriately.
          The pointer in *head should be initialized to a null pointer
          before the first call to any of these functions.

          The plrtfree function will dispose of a Rtext list that is
          no longer needed.  The user's code is responsible for dis-
          carding any strings, bitmaps, panels, or user data that the
          list may point to.

     SOURCE
          /sys/src/libpanel

     SEE ALSO
          plbutton(2), plinitbutton(2), graphics(2)
          Tom Duff, ``A quick introduction to the panel library''.

     Page 7                       Plan 9             (printed 4/25/24)