NAME
    Tk::HListbox - Tk Listbox widget supporting images and text entries,
    Tk::HList-based drop-in replacement for Tk::Listbox.

SYNOPSIS
    *$listbox* = *$parent*->HListbox(?*options*?);

DESCRIPTION
    The HListbox method creates a new window (given by the $widget argument)
    and makes it into an HListbox widget. Additional options, described
    above, may be specified on the command line or in the option database to
    configure aspects of the listbox such as its colors, font, text, and
    relief. The HListbox command returns its $widget argument. At the time
    this command is invoked, there must not exist a window named $widget,
    but $widget's parent must exist.

    An HListbox is a widget that displays a list of strings, images, or both
    one per line. When first created, a new HListbox has no elements.
    Elements may be added or deleted using methods described below. In
    addition, one or more elements may be selected as described below. If an
    HListbox is exporting its selection (see exportSelection option), then
    it will observe the standard X11 protocols for handling the selection.
    HListbox selections are available as type STRING; the value of the
    selection will be the "text" of the selected elements, returned as an
    array of zero or more elements.

    It is not necessary for all the elements to be displayed in the HListbox
    window at once; commands described below may be used to change the view
    in the window. HListboxes allow scrolling in both directions using the
    standard xScrollCommand and yScrollCommand options. They also support
    scanning, as described below.

STANDARD OPTIONS
    -background -borderwidth -cursor -disabledforeground -exportselection
    -font -foreground -height -highlightbackground -highlightcolor
    -highlightthickness -offset -relief -selectbackground -selectborderwidth
    -selectforeground -setgrid -state -takefocus -width -xscrollcommand
    -yscrollcommand

    See Tk::options for details of the standard options.

WIDGET-SPECIFIC OPTIONS
    Name: Entries
        Entries (rows) are added to HListbox vertically as rows, one per row
        (line) using either the insert method or inserting into a tied
        array. Entries can be either a text string (just like a standard
        Tk::Listbox entry), an image (a Tk::Photo object), or a hashref
        containing options specifying both, along with any other desired
        Tk::HList-valid *options* (see below). Example:
        $listbox->insert('end', {-image => $image, -text => 'string'});
        Options for the referenced hash include:

        -hidden => 1 | 0
            Specifies whether or not the entry should be visible or hidden:
            (0 (false) for visible, 1 (true) for hidden). Default: 0 -
            visible.

        -indicatoritemtype => ['text' | 'image' | 'imagetext']
            Specify an "indicator" of this type.

        -indicatorimage = $image
            Special image to be displayed next to entry (in addition to any
            other image specified in the entry).

        -indicatortext = 'text'
            Special text to be displayed next to entry (in addition to any
            other image specified in the entry).

        -itemtype => ['text' | 'image' | 'imagetext']
            Specifies the type of display item of this entry. Can be
            *"text"*, *"image"*, or *"imagetext"*. Default: Whatever is
            specified, if anything, for the widget, (see -itemtype under
            WIDGET OPTIONS below). If not specified there, then the default
            is *"text"*, though *"imagetext"* allows for either or both an
            image or text.

        -textanchor => ['n', 's', 'e', 'w']
            Side of text the IMAGE is displayed on. Default: *'w'* (West /
            left, ie. image before text)

        -style => $ImageStyleObject
            Use an already-defined HList ItemStyle object (see Tk::ItemStyle
            and Tk::DItem)

        -sort => 'value', -user => 'value'
            Specifies user-specific data to be kept stored with the entry
            but not displayed. Such data would most likely be a string, but
            could be a reference to pretty much anything. Tk::HMListbox
            makes use of the -sort field for user-control of column sorting,
            refer to it's documentation for examples.

        -text $string
            Specifies a "text" entry. $string represents the text to be
            displayed in the entry.

            These options are not passed to functions, but retained with
            data, useful for saving info with an entry for one's own use.

            For example, one could put text in a *-sort* option of say, an
            image-only entry and then retrieve it in a sort function like
            "sort { $a->{-sort} cmp $b->{-sort} }".

            Any other option, other than these or the standard applicable
            widget options, such as -background, etc. are treated as "Style"
            options and sent to the default ItemStyle for the data type.
            NOTE: Under the current implementation any "Style" options
            supplied with an entry will be applied to ALL entries of that
            "type" (ie. "image", "imagetext", or "text") in the listbox. To
            force a specific entry to have a different "style", define an
            ItemStyle object and use the -style option.

    Name: activeForeground
    Class: activeForeground
    Switch: -activeforeground
        Specifies an alternate color for the foreground of the "active"
        entry (the one the text cursor is on). This entry is also shown with
        a hashed box around it. The "activebackground" color, however, is
        always fixed as the same color as the the widget's background.
        Default: same color as the widget's foreground color.

    Name: browsecmd
    Class: BrowseCmd
    Switch: -browsecmd
        Specifies a perl/Tk callback to be executed when the user browses
        through the entries in the HList widget.

    Name: command
    Class: Command
    Switch: -command
        Specifies the perl/Tk callback to be executed when the user invokes
        a list entry in the HList widget. Normally the user invokes a list
        entry by double-clicking it or pressing the Return key.

    Switch: -gap value
        The amount of space between the image and text in rows that have
        both.

        Default: 4 (pixels)

    Name: height
    Class: Height
    Switch: -height
        Specifies the desired height for the window, in number of
        characters. If zero or less, then the desired height for the window
        is based on the default for HList, which seems to be about 7 lines.
        WARNING: This is NOT accurate, ie. specifying a -height of 8 will
        typically display about 6-6 1/2 rows of text in the default font.
        Sorry, but this is a bug in the underlying Tk::HList widget.

    Name: indicator
    Class: Indicator
    Switch -indicator
        Reserves space for and allows for another image next to the entry,
        which HList calls an "indicator", which, unlike a normal "image" in
        an entry, can be attached to a callback routine (-indicatorcmd) to
        be invoked when the indicator image is clicked with the mouse,
        rather than the entry simply being selected. By default (if no
        *-textanchor* option given, the indicator image will appear to the
        left of the entry.

    Name: indicatorCmd
    Class: IndicatorCmd
    Switch -indicatorcmd
        Subroutine reference to be invoked when an indicator image is
        clicked.

    Name: -ipadx
        Specify horizontal padding style in pixels around the image for the
        rows in the listbox which are type *image* or *imagetext*. Default:
        0

    Name: -ipady
        Specify vertical padding style in pixels around the image for the
        rows in the listbox which are type *image* or *imagetext*. NOTE:
        This changes the height of the affected rows. Default: 1 (and
        setting to 0 is the same as 1).

    Name: itemType
    Class: ItemType
    Switch: -itemtype
        Specifies the default type of display item. Can be "text", "image",
        or "imagetext". The default is "text", though "imagetext" allows for
        either or both an image or text.

    Name: listVariable
    Class: Variable
    Switch: -listvariable
        Specifies the reference of a variable. The value of the variable is
        an array to be displayed inside the widget; if the variable value
        changes then the widget will automatically update itself to reflect
        the new value. Attempts to unset a variable in use as a
        -listvariable may fail without error.

        The listvariable reference is "TIEd" to the HListbox widget just as
        if one has done: "tie @listvariable, 'Tk::HListbox',
        $HListboxwidget, (ReturnType => 'index);" immediately after defining
        $HListboxwidget using the "tie @array" feature.

    Name: selectBackground
    Class: SelectBackground
    Switch: -selectbackground
        Specifies an alternate background color for item(s) currently
        "selected". Default: a slightly brighter shade of the widget's
        current background color.

    Name: selectForeground
    Class: SelectForeground
    Switch: -selectforeground
        Specifies an alternate foreground color for item(s) currently
        "selected". Default: the widget's current foreground color.

    Name: selectMode
    Class: SelectMode
    Switch: -selectmode
        Specifies one of several styles for manipulating the selection. The
        value of the option may be arbitrary, but the default bindings
        expect it to be either single, browse, multiple, extended or
        dragdrop; the default value is browse.

    Name: -showcursoralways
    Class: -showcursoralways
    Switch: -showcursoralways
        Starting with version 2.4, Tk::HListbox no longer displays the
        keyboard cursor (active element) when the HListbox widget does not
        have the keyboard focus, in order to be consistent with the
        behaviour of Tk::Listbox. This option, when set to 1 (or a "true"
        value) restores the pre-v2.4 behaviour of always showing the
        keyboard cursor. Default *0* (False).

    Name: state
    Class: State
    Switch: -state
        Specifies one of two states for the listbox: normal or disabled. If
        the listbox is disabled then items may not be inserted or deleted,
        items are drawn in the -disabledforeground color, and selection
        cannot be modified and is not shown (though selection information is
        retained).

    Name: takeFocus
    Class: TakeFocus
    Switch: -takefocus
        There are actually three different focusing options: Specify 1 to
        both allow the widget to take keyboard focus itself and to enable
        grabbing the keyboard focus when a user clicks on a row in the
        listbox. Specify '' to allow the widget to take focus (via the <TAB>
        circulate order) but do not grab the focus when a user clicks on
        (selects) a row. This is the default focusing model. Specify 0 to
        not allow the widget to receive the keyboard focus.

    Name: -tpadx => *number*
        Specify horizontal padding style in pixels around the text for the
        rows in the listbox which are type *text*. Default: 2

    Name: -tpady => *number*
        Specify vertical padding style in pixels around the text for the
        rows in the listbox which are type *text*. NOTE: This changes the
        height of the affected rows. Default (seems to be): 2 (and setting
        to 0 is the same as 2).

    Name: width
    Class: Width
    Switch: -width
        Specifies the desired width for the window in characters. If the
        font doesn't have a uniform width then the width of the character
        ``0'' is used in translating from character units to screen units.
        If zero or less, then the desired width for the window is made just
        large enough to hold all the elements in the listbox.

LISTBOX OPTIONS AND METHODS NOT (YET?) SUPPORTED BY HLISTBOX
    Name: activeStyle
    Class: ActiveStyle
    Switch: -activestyle
        Ignored (not implemented in HList).

        For the most part, Tk::HListbox can be used as drop-in replacement
        for the Tk::Listbox widget when you need to use images instead of or
        in addition to text values, or need other Tk::HListbox - specific
        features such as hidden or disabled entries, callbacks, etc.

INDICES
    Many of the methods for HListboxes take one or more indices as
    arguments. An index specifies a particular element of the listbox, in
    any of the following ways:

    *number*
        Specifies the element as a numerical index, where 0 corresponds to
        the first element in the listbox.

    active
        Indicates the element that has the location cursor. This element
        will be displayed with a dashed-line frame border when the listbox
        has the keyboard focus, and it is specified with the activate
        method.

    anchor
        Indicates the anchor point for the selection, which is set with the
        selection anchor method.

    end Indicates the end (last element) of the HListbox. For most commands
        this refers to the last element in the HListbox, but for a few
        commands such as index and insert it refers to the element just
        after the last one.

    @*x*,*y*
        Indicates the element that covers the point in the HListbox window
        specified by *x* and *y* (in pixel coordinates). If no element
        covers that point, then the closest element to that point is used.

    In the method descriptions below, arguments named *index*, *first*, and
    *last* always contain text indices in one of the above forms.

WIDGET METHODS
    The HListbox method creates a widget object. This object supports the
    configure and cget methods described in Tk::options which can be used to
    enquire and modify the options described above. The widget also inherits
    all the methods provided by the generic Tk::Widget class.

    The following additional methods are available for HListbox widgets:

    *$listbox*->activate(*index*)
        Sets the active element and the selection anchor to the one
        indicated by *index*. If *index* is outside the range of elements in
        the listbox then the closest element is activated. The active
        element is drawn similar to a "selected" element with a thin hashed
        border, and its index may be retrieved with the index active or
        anchor.

    *$listbox*->bbox(*index*)
        Returns a list of four numbers describing the bounding box of the
        text in the element given by *index*. The first two elements of the
        list give the x and y coordinates of the upper-left corner of the
        screen area covered by the text (specified in pixels relative to the
        widget) and the last two elements give the width and height of the
        area, in pixels. If no part of the element given by *index* is
        visible on the screen, or if *index* refers to a non-existent
        element, then the result is an empty string; if the element is
        partially visible, the result gives the full area of the element,
        including any parts that are not visible.

    *$listbox*->curselection
        Returns a list containing the numerical indices of all of the
        elements in the HListbox that are currently selected. If there are
        no elements selected in the listbox then an empty list is returned.

    *$listbox*->delete(*first, *?*last*?)
        Deletes one or more elements of the HListbox. *First* and *last* are
        indices specifying the first and last elements in the range to
        delete. If *last* isn't specified it defaults to *first*, i.e. a
        single element is deleted.

    *$listbox*->findIndex(*string*?)
        Given the text of an entry, return the index of the first entry
        whose text matches the string, or *<undef*> if no matches.

    $listbox->fixListSize(*width*, *height*)
        Will fix the height and width of the HListbox, caused by the
        underlying HList, when non-default fonts are used.

        The *width* and *height* values are the required character width and
        the number of rows in the listbox.

    *$listbox*->fixPalette()
        Under certain situations, changing the color theme via
        $mainwin->setPalette(...) does not always update do to the myriad of
        subwidgets and color options supported. Calling this method should
        fully update everything in the widget that have not been
        individually set by the user.

    *$listbox*->get(*first, *?*last*?)
        If *last* is omitted, returns the contents of the listbox element
        indicated by *first*, or an empty string if *first* refers to a
        non-existent element. If *last* is specified, the command returns a
        list whose elements are all of the listbox elements between *first*
        and *last*, inclusive. Both *first* and *last* may have any of the
        standard forms for indices.

    *$listbox*->getEntry(*index*?)
        Given an index, returns the HList "entry" value, only useful with
        lower-level HList functions. Returns *<undef*> if no matches.

    $listbox->getListHeight(*height*)
        Will return the correct height in pixels, of the HListbox, when a
        non-default -listfont is used.

        *height* is the required number of rows for the listbox.

    $listbox->getListWidth(*width*)
        Will return the correct width, in pixels, of the HListbox, when a
        non-default -listfont is used.

        *width* is the required width in characters for the listbox.

    *$listbox*->hide([*-entry* => ] *index*)
        Given an index, sets the entry to "hidden" so that it does not
        display in the listbox (but maintains it's index. The "-entry"
        argument is unnecessary, but retained for Tk::HList compatability.

    *$listbox*->show([*-entry* => ] *index*)
        Given an index, sets the entry to "not hidden" (the default) so that
        it is displayed in the listbox.

    *$listbox*->index(*index*)
        Returns the integer index value that corresponds to *index*. If
        *index* is end the return value is a count of the number of elements
        in the listbox (not the index of the last element).

    *$listbox*->insert(*index, *?*element, element, ...*?)
        Inserts zero or more new elements (entries) in the list just before
        the element given by *index*. If *index* is specified as "end" then
        the new elements are added to the end of the list. Returns an empty
        string. If the *index* is not "end", the list will be automatically
        inserted in reverse order so that the entire list is inserted in the
        proper order before the element currently identified by the *index*.

    *$listbox*->itemcget(*index*, *option*)
        Returns the current value of the item configuration option given by
        *option*. Option may have any of the values accepted by the listbox
        itemconfigure command or by HList, including ItemStyles.

    *$listbox*->itemconfigure(*index, *?*option, value, option, value,
    ...*?)
        Query or modify the configuration options of an item in the
        HListbox. If no option is specified, returns a list describing all
        of the available options for the item (see Tk_ConfigureInfo for
        information on the format of this list). If option is specified with
        no value, then the command returns a list describing the one named
        option (this list will be identical to the corresponding sublist of
        the value returned if no option is specified). If one or more
        option-value pairs are specified, then the command modifies the
        given widget option(s) to have the given value(s); in this case the
        command returns an empty string. The following options are currently
        supported for items:

    *$listbox*->ItemStyle(*itemtype, *?*option, value, ...*?)
        HList method to create a display style for the *-style* entry
        option. NOTE: It's better to change most display properties by
        listing them and their values when inserting entries since any
        HListbox-wide style options specified when creating the HListbox
        widget, ie. *-foreground*, etc. are NOT copied over into the style
        object.

        -background => *color*
            *Color* specifies the background color to use when displaying
            the item. It may have any of the forms accepted by Tk_GetColor.

        -foreground => *color*
            *Color* specifies the foreground color to use when displaying
            the item. It may have any of the forms accepted by Tk_GetColor.
            NOTE: may be returned as "-fg".

        -selectbackground => *color*
            *Color* specifies the background color to use when displaying
            the item while it is selected. It may have any of the forms
            accepted by Tk_GetColor.

        -selectforeground => *color*
            *Color* specifies the foreground color to use when displaying
            the item while it is selected. It may have any of the forms
            accepted by Tk_GetColor.

    *$listbox*->nearest(*y*)
        Given a y-coordinate within the listbox window, this command returns
        the index of the (visible) listbox element nearest to that
        y-coordinate.

    $listbox->nearestToIndex(*index*)
        Given a zero based *index* within the listbox window, this command
        returns the index of the (visible) listbox element nearest to the
        *index*.

        If there is no visible bounding box associated with the zero based
        *index*, then *undef* is returned.

    $listbox->nearestToHListIndex(*index*)
        Given a HList *index* within the listbox window, this command
        returns the index of the (visible) listbox element nearest to the
        HList *index*.

        If there is no visible bounding box associated with the HList
        *index*, then *undef* is returned.

    *$listbox*->scan(*option, args*)
        This command is used to implement scanning on listboxes. It has two
        forms, depending on *option*:

        *$listbox*->scanMark(*x, y*)
                Records *x* and *y* and the current view in the listbox
                window; used in conjunction with later scan dragto commands.
                Typically this command is associated with a mouse button
                press in the widget. It returns an empty string.

        *$listbox*->scanDragto(*x, y*.)
                This command computes the difference between its *x* and *y*
                arguments and the *x* and *y* arguments to the last scan
                mark command for the widget. It then adjusts the view by 10
                times the difference in coordinates. This command is
                typically associated with mouse motion events in the widget,
                to produce the effect of dragging the list at high speed
                through the window. The return value is an empty string.

    *$listbox*->see(*index*)
        Adjust the view in the HListbox so that the element given by *index*
        is visible. If the element is already visible then the command has
        no effect; if the element is near one edge of the window then the
        listbox scrolls to bring the element into view at the edge;
        otherwise the listbox scrolls to center the element.

    *$listbox*->selection(*option, arg*)
        This command is used to adjust the selection within a listbox. It
        has several forms, depending on *option*:

        *$listbox*->selectionAnchor(*index*)
                Sets the selection anchor to the element given by *index*.
                If *index* refers to a non-existent element, then the
                closest element is used. The selection anchor is the end of
                the selection that is fixed while dragging out a selection
                with the mouse. The index anchor may be used to refer to the
                anchor element.

        *$listbox*->selectionClear(*first, *?*last*?)
                If any of the elements between *first* and *last*
                (inclusive) are selected, they are deselected. The selection
                state is not changed for elements outside this range.

        *$listbox*->selectionIncludes(*index*)
                Returns 1 if the element indicated by *index* is currently
                selected, 0 if it isn't.

        *$listbox*->selectionSet(*first, *?*last*?)
                Selects all of the elements in the range between *first* and
                *last*, inclusive, without affecting the selection state of
                elements outside that range.

    *$listbox*->size
        Returns a decimal string indicating the total number of elements in
        the listbox.

    *$listbox*->xview(*args*)
        This command is used to query and change the horizontal position of
        the information in the widget's window. It can take any of the
        following forms:

        *$listbox*->xview
                Returns a list containing two elements. Each element is a
                real fraction between 0 and 1; together they describe the
                horizontal span that is visible in the window. For example,
                if the first element is .2 and the second element is .6, 20%
                of the listbox's text is off-screen to the left, the middle
                40% is visible in the window, and 40% of the text is
                off-screen to the right. These are the same values passed to
                scrollbars via the -xscrollcommand option.

        *$listbox*->xview(*index*)
                Adjusts the view in the window so that the character
                position given by *index* is displayed at the left edge of
                the window. Character positions are defined by the width of
                the character 0.

        *$listbox*->xviewMoveto( *fraction* );
                Adjusts the view in the window so that *fraction* of the
                total width of the listbox text is off-screen to the left.
                *fraction* must be a fraction between 0 and 1.

        *$listbox*->xviewScroll( *number, what* );
                This command shifts the view in the window left or right
                according to *number* and *what*. *Number* must be an
                integer. *What* must be either units or pages or an
                abbreviation of one of these. If *what* is units, the view
                adjusts left or right by *number* character units (the width
                of the 0 character) on the display; if it is pages then the
                view adjusts by *number* screenfuls. If *number* is negative
                then characters farther to the left become visible; if it is
                positive then characters farther to the right become
                visible.

    *$listbox*->yview(*?args*?)
        This command is used to query and change the vertical position of
        the text in the widget's window. It can take any of the following
        forms:

        *$listbox*->yview
                Returns a list containing two elements, both of which are
                real fractions between 0 and 1. The first element gives the
                position of the listbox element at the top of the window,
                relative to the listbox as a whole (0.5 means it is halfway
                through the listbox, for example). The second element gives
                the position of the listbox element just after the last one
                in the window, relative to the listbox as a whole. These are
                the same values passed to scrollbars via the -yscrollcommand
                option.

        *$listbox*->yview(*index*)
                Adjusts the view in the window so that the element given by
                *index* is displayed at the top of the window.

        *$listbox*->yviewMoveto( *fraction* );
                Adjusts the view in the window so that the element given by
                *fraction* appears at the top of the window. *Fraction* is a
                fraction between 0 and 1; 0 indicates the first element in
                the listbox, 0.33 indicates the element one-third the way
                through the listbox, and so on.

        *$listbox*->yviewScroll( *number, what* );
                This command adjusts the view in the window up or down
                according to *number* and *what*. *Number* must be an
                integer. *What* must be either units or pages. If *what* is
                units, the view adjusts up or down by *number* lines; if it
                is pages then the view adjusts by *number* screenfuls. If
                *number* is negative then earlier elements become visible;
                if it is positive then later elements become visible.

EXAMPLES
    #!/usr/bin/perl

            use Tk;
            use Tk::HListbox;

            my ( @array, $scalar, $other );
            my %options = ( ReturnType => "index" );

            my $MW = MainWindow->new();
            my $licon=$MW->Photo(-file => '/usr/share/pixmaps/smallicons/Penguin.xpm');  #ICON IMAGE
            my $wicon=$MW->Photo(-file => '/usr/share/pixmaps/smallicons/tiny_windowsxp.xpm');  #ICON IMAGE
            my $lbox = $MW->Scrolled('HListbox',
                            -scrollbars => 'se', 
                            -selectmode => 'extended',
                            -itemtype => 'imagetext',
                            -indicator => 1,
                            -indicatorcmd => sub {
                                    print STDERR "---indicator clicked---(".join('|',@_).")\n";
                            },
                            -browsecmd => sub { 
                                    print STDERR "---browsecmd!---(".join('|',@_).")\n";
                            },
            )->pack(-fill => 'y', -expand => 1);

            $MW->Button(   #MAIN WINDOW BUTTON TO QUIT.
                            -text => 'Bonus Tests', 
                            -underline => 0,
                            -command => sub
            {
            #FETCH AND PRINT OUT THE SELECTED ITEMS:
                    my @v = $lbox->curselection;
                    print "--SELECTED=".join('|', @v)."= vcnt=$#v= MODE=".$lbox->cget('-selectmode')."=\n";
                    for (my $i=0;$i<=$#v;$i++)
                    {
                            print "--selected($i)=".$lbox->get($v[$i])."=\n";
                    }
            #PRINT WHETHER THE LAST ITEM IS CURRENTLY SELECTED (2 WAYS):
                    print "--select includes last one =".$lbox->selectionIncludes('end')."=\n";
                    print "--select includes last one =".$lbox->selection('includes','end')."=\n";
            #FETCH THE OLD ANCHOR AND SET THE ANCHOR TO THE 2ND ITEM:
                    my $anchorWas = $lbox->index('anchor');
                    $lbox->selectionAnchor(8);
                    my $anchorNow = $lbox->index('anchor');
            #DELETE THE 4TH ITEM & ****TURN OFF INDICATORS!**** TO SHOW NORMAL VIEW:
                    $lbox->delete(4);
                    $lbox->configure(-indicator => 0);
            #SET THE VIEWPORT TO SHOW THE FIRST SELECTED ITEM:
                    $lbox->yview($v[0]);
            #PRINT THE DATA RETURNED BY yview() AND THE LAST ITEM;
                    my @yview = $lbox->yview;
                    my $last = $lbox->index('end');
                    print "--YVIEW=".join('|',@yview)."= last=$last=\n";
            #FETCH THE INDEX OF THE LAST ITEM:
                    #FETCH AND DISPLAY SOME ATTRIBUTES:
                    print "--anchor was=$anchorWas= now=$anchorNow= yview=".join('|',@yview)."=\n";
                    print "-reqheight=".$lbox->reqheight."= height=".$lbox->cget('-height')."= size=".$lbox->size."=\n";
            #PRINT OUT THE VALUES OF THE TIED VARIABLES:
                    print "-scalar=".join('|',@{$scalar})."= array=".join('|',@array)."= other=".join('|',@{$other})."=\n";
            #RECONFIGURE 2ND ITEM TO FOREGROUND:=GREEN:
                    $lbox->itemconfigure(1,'-fg', 'green');
            #FETCH THE HList STYLE OBJECT FOR 2ND ITEM:
                    print "-itemcget(1)=".$lbox->itemcget(1, '-style')."=\n";
            #FETCH JUST THE Listbox FOREGROUND COLOR FOR 2ND ITEM:
                    print "-itemcget(2)=".$lbox->itemcget(1, '-fg')."=\n";
            #FETCH THE "NEAREST" INDEX TO THE 2ND ITEM:
                    print "-nearest(1)=".$lbox->nearest(1)."=\n";
            #ADD AN ELEMENT VIA THE TIED ARRAY:
                    push @array, {-image => $licon, -text => 'ArrayAdd!'};
            #DELETE THE LAST ITEM USING THE TIED ARRAY:
                    pop @array;
            #FIND AND DISPLAY THE INDEX OF THE TEXT ENTRY "Y":
                    print "-Index of 'Y' =".$lbox->findIndex('Y')."=\n";
            }
            )->pack(
                            -side => 'bottom'
            );
            $MW->Button(   #MAIN WINDOW BUTTON TO QUIT.
                            -text => 'Quit', 
                            -underline => 0,
                            -command => sub { print "ok 5\n..done: 5 tests completed.\n"; exit(0) }
            )->pack(
                            -side => 'bottom'
            );

            #ADD SOME ITEMS (IMAGE+TEXT) TO OUR LISTBOX THE TRADITIONAL WAY:
                    my @list = ( 
                            {-image => $licon, -text => 'a' },
                            {-image => $wicon, -text => 'bbbbbbbbbbbbbbbbbbbB', -foreground => '#0000FF' },
                            {-text => 'c', -image => $licon },
                            {-text => 'd:image & indicator!', -image => $licon, -indicatoritemtype, 'image', -indicatorimage => $wicon },
                            {-image => $licon, -text => 'e' },
                            {-image => $licon, -text => 'f:Switch sides!', -textanchor => 'w' },
                            {-image => $licon, -text => 'z:Next is Image Only!' },
                            $licon
                    );
                    $lbox->insert('end', @list );
                    @list = ();
            #ADD A BUNCH MORE JUST BEFORE THE 7TH ITEM ("
                    foreach my $i ('G'..'Y')
                    {
                            push @list, {-image => $licon, -text => $i};
                    }
                    $lbox->insert(6, @list );

            #FETCH THE 2ND ITEM AND DISPLAY IT'S TEXT:
                    $_ = $lbox->get(1);
                    if (ref $_) {
                            print "-2nd value=$_= TEXT=".$_->{'-text'}."=\n";
                    } else {
                            print "-2nd value=$_=\n";
                    }
            #SET THE 3RD AND 5TH ITEMS AS INITIALLY-SELECTED:
                    $lbox->selectionSet(2,4);
            #AND ONE WITH AN "INDICATOR IMAGE" JUST BEFORE THE 4TH ITEM:
                    $lbox->insert(3, 'TextOnly at 3', 
                                    {'-text' => '<Click Indicator Icon', '-indicatoritemtype', 'image', '-indicatorimage' => $wicon});
            #DISPLAY A LIST OF ALL THE CURRENT ITEMS IN THE LISTBOX:
                    print "--current choices=".join('|',$lbox->get(0, 'end'))."=\n";

            #TIE SOME VARIABLES TO THE LISTBOX:
                    tie @array, "Tk::HListbox", $lbox;
                    tie $scalar, "Tk::HListbox", $lbox;
                    tie $other, "Tk::HListbox", $lbox, %options;

                    MainLoop;

    __END__

DEFAULT BINDINGS
    Tk automatically creates class bindings for listboxes that give them
    Motif-like behavior. Much of the behavior of a listbox is determined by
    its selectMode option, which selects one of four ways of dealing with
    the selection.

    If the selection mode is single or browse, at most one element can be
    selected in the listbox at once. In both modes, clicking button 1 on an
    element selects it and deselects any other selected item. In browse mode
    it is also possible to drag the selection with button 1.

    If the selection mode is multiple or extended, any number of elements
    may be selected at once, including discontiguous ranges. In multiple
    mode, clicking button 1 on an element toggles its selection state
    without affecting any other elements. In extended mode, pressing button
    1 on an element selects it, deselects everything else, and sets the
    anchor to the element under the mouse; dragging the mouse with button 1
    down extends the selection to include all the elements between the
    anchor and the element under the mouse, inclusive.

    Most people will probably want to use browse mode for single selections
    and extended mode for multiple selections; the other modes appear to be
    useful only in special situations.

    Any time the selection changes in the listbox, the virtual event
    <<ListboxSelect>> will be generated. It is easiest to bind to this event
    to be made aware of any changes to listbox selection.

    In addition to the above behavior, the following additional behavior is
    defined by the default bindings:

    [1] In extended mode, the selected range can be adjusted by pressing
        button 1 with the Shift key down: this modifies the selection to
        consist of the elements between the anchor and the element under the
        mouse, inclusive. The un-anchored end of this new selection can also
        be dragged with the button down.

    [2] In extended mode, pressing button 1 with the Control key down starts
        a toggle operation: the anchor is set to the element under the
        mouse, and its selection state is reversed. The selection state of
        other elements isn't changed. If the mouse is dragged with button 1
        down, then the selection state of all elements between the anchor
        and the element under the mouse is set to match that of the anchor
        element; the selection state of all other elements remains what it
        was before the toggle operation began.

    [3] If the mouse leaves the HListbox window with button 1 down, the
        window scrolls away from the mouse, making information visible that
        used to be off-screen on the side of the mouse. The scrolling
        continues until the mouse re-enters the window, the button is
        released, or the end of the listbox is reached.

    [4] Mouse button 2 may be used for scanning. If it is pressed and
        dragged over the listbox, the contents of the listbox drag at high
        speed in the direction the mouse moves.

    [5] If the Up or Down key is pressed, the location cursor (active
        element) moves up or down one element. If the selection mode is
        browse or extended then the new active element is also selected and
        all other elements are deselected. In extended mode the new active
        element becomes the selection anchor.

    [6] In extended mode, Shift-Up and Shift-Down move the location cursor
        (active element) up or down one element and also extend the
        selection to that element in a fashion similar to dragging with
        mouse button 1.

    [7] The Left and Right keys scroll the listbox view left and right by
        the width of the character 0.

        Control-Left and Control-Right scroll the listbox view left and
        right by the width of the window.

    [8] The Prior and Next keys scroll the listbox view up and down by one
        page (the height of the window).

        Control-Prior and Control-Next scroll the listbox view up and down
        by one page while selecting a page's worth of items.

    [9] The Home and End keys scroll the listbox horizontally to the left
        and right edges, respectively.

    [10]
        Control-Home sets the location cursor to the the first element in
        the listbox, selects that element, and deselects everything else in
        the listbox.

    [11]
        Control-End sets the location cursor to the the last element in the
        listbox, selects that element, and deselects everything else in the
        listbox.

    [12]
        In extended mode, Control-Shift-Home extends the selection to the
        first element in the listbox and Control-Shift-End extends the
        selection to the last element.

    [13]
        In multiple mode, Control-Shift-Home moves the location cursor to
        the first element in the listbox and Control-Shift-End moves the
        location cursor to the last element.

    [14]
        The space and Select keys toggle a selection at the location cursor
        (active element) just as if mouse button 1 had been pressed over
        this element.

    [15]
        In extended mode, Control-Shift-space and Shift-Select extend the
        selection to the active element just as if button 1 had been pressed
        with the Shift key down.

    [16]
        In extended mode, the Escape key cancels the most recent selection
        and restores all the elements in the selected range to their
        previous selection state. NOTE: This may not be fully working
        correctly.

    [17]
        Control-slash selects everything in the widget, except in single and
        browse modes, in which case it selects the active element and
        deselects everything else.

    [18]
        Control-backslash deselects everything in the widget, except in
        browse mode where it has no effect.

    [19]
        The F16 key (labelled Copy on many Sun workstations) or Meta-w
        copies the selection in the widget to the clipboard, if there is a
        selection.

    [20]
        We've added <Ctrl-<Prior>> and <Ctrl-<Next>> bindings to scroll the
        listbox view up and down by one page while selecting a page's worth
        of items.

    The behavior of HListboxes can be changed by defining new bindings for
    individual widgets or by redefining the class bindings.

TIED INTERFACE
    The Tk::HListbox widget can also be tied to a scalar or array variable,
    with different behaviour depending on the variable type, with the
    following tie commands:

       use Tk;

       my ( @array, $scalar, $other );
       my %options = ( ReturnType => "index" );

       my $MW = MainWindow->new();
       my $lbox = $MW->HListbox()->pack();

       my @list = ( "a", "b", "c", "d", "e", "f" );
       $lbox->insert('end', @list );

       tie @array, "Tk::HListbox", $lbox
       tie $scalar, "Tk::HListbox", $lbox;
       tie $other, "Tk::HListbox", $lbox, %options;

    currently only one modifier is implemented, a 3 way flag for tied
    scalars "ReturnType" which can have values "element", "index" or "both".
    The default is "element".

    Tied Arrays
        If you tie an array to the HListbox you can manipulate the items
        currently contained by the box in the same manner as a normal array,
        e.g.

            print @array;
            push(@array, @list);
            my $popped = pop(@array);
            my $shifted = shift(@array);
            unshift(@array, @list);
            delete $array[$index];
            print $string if exists $array[$i];
            @array = ();
            splice @array, $offset, $length, @list

        The delete function is implemented slightly differently from the
        standard array implementation. Instead of setting the element at
        that index to undef it instead physically removes it from the
        HListbox. This has the effect of changing the array indices, so for
        instance if you had a list on non-continuous indices you wish to
        remove from the HListbox you should reverse sort the list and then
        apply the delete function, e.g.

             my @list = ( 1, 2, 4, 12, 20 );
             my @remove = reverse sort { $a <=> $b } @list;
             delete @array[@remove];

        would safely remove indices 20, 12, 4, 2 and 1 from the HListbox
        without problems. It should also be noted that a similar warning
        applies to the splice function (which would normally be used in this
        context to perform the same job).

    Tied Scalars
        Unlike tied arrays, if you tie a scalar to the HListbox you can
        retrieve the currently selected elements in the box as an array
        referenced by the scalar, for instance

            my @list = ( "a", "b", "c", "d", "e", "f" );
            $lbox->insert('end', sort @list );
            $lbox->selectionSet(1);

        inserts @list as elements in an already existing listbox and selects
        the element at index 1, which is "b". If we then

             print @$selected;

        this will return the currently selected elements, in this case "b".

        However, if the "ReturnType" argument is passed when tying the
        HListbox to the scalar with value "index" then the indices of the
        selected elements will be returned instead of the elements
        themselves, ie in this case "1". This can be useful when
        manipulating both contents and selected elements in the HListbox at
        the same time.

        Importantly, if a value "both" is given the scalar will not be tied
        to an array, but instead to a hash, with keys being the indices and
        values being the elements at those indices

        You can also manipulate the selected items using the scalar.
        Equating the scalar to an array reference will select any elements
        that match elements in the HListbox, non-matching array items are
        ignored, e.g.

            my @list = ( "a", "b", "c", "d", "e", "f" );
            $lbox->insert('end', sort @list );
            $lbox->selectionSet(1);

        would insert the array @list into an already existing HListbox and
        select element at index 1, i.e. "b"

            @array = ( "a", "b", "f" );
            $selected = \@array;

        would select elements "a", "b" and "f" in the HListbox.

        Again, if the "index" we indicate we want to use indices in the
        options hash then the indices are use instead of elements, e.g.

            @array = ( 0, 1, 5 );
            $selected = \@array;

        would have the same effect, selecting elements "a", "b" and "f" if
        the $selected variable was tied with %options = ( ReturnType =>
        "index" ).

        If we are returning "both", i.e. the tied scalar points to a hash,
        both key and value must match, e.g.

            %hash = ( 0 => "a", 1 => "b", 5 => "f" );
            $selected = \%hash;

        would have the same effect as the previous examples.

        It should be noted that, despite being a reference to an array (or
        possibly a hash), you still can not copy the tied variable without
        it being untied, instead you must pass a reference to the tied
        scalar between subroutines.

AUTHOR
    Jim Turner, "<https://metacpan.org/author/TURNERJW>".

COPYRIGHT
    Copyright (c) 2015-2022 Jim Turner "<mailto://turnerjw784@yahoo.com>".
    All rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    This is a derived work from Tk::Listbox and Tk::HList.

KEYWORDS
    hlistbox, listbox, hlist

SEE ALSO
    Tk::HList, Tk::Listbox, Tk::ItemStyle, Tk::DItem.

