Curses-UI

 view release on metacpan or  search on metacpan

lib/Curses/UI/Popupmenu.pm  view on Meta::CPAN


use vars qw(
    $VERSION 
    @ISA
);

$VERSION = '1.10';

@ISA = qw(
    Curses::UI::Widget 
);

my %routines = (
    'loose-focus'    => \&loose_focus,
    'open-popup'     => \&open_popup,
    'select-next'    => \&select_next,
    'select-prev'    => \&select_prev,
    'mouse-button1'  => \&mouse_button1,
);

my %bindings = (
    CUI_TAB()        => 'loose-focus',
    KEY_BTAB()       => 'loose-focus',
    KEY_ENTER()      => 'open-popup',
    KEY_RIGHT()      => 'open-popup',
    "l"              => 'open-popup',
    CUI_SPACE()      => 'open-popup',
    KEY_DOWN()       => 'select-next',
    "j"              => 'select-next',
    KEY_UP()         => 'select-prev',
    "k"              => 'select-prev',
);

sub new ()
{
    my $class = shift;

    my %userargs = @_;
    keys_to_lowercase(\%userargs);

    my %args = (
        -parent       => undef,    # the parent window
        -width        => undef,    # the width of the checkbox
        -x            => 0,        # the horizontal position rel. to parent
        -y            => 0,        # the vertical position rel. to parent
        -values       => [],       # values
        -labels       => {},       # labels for the values
        -selected     => undef,    # the current selected value
        -wraparound   => undef,    # wraparound? 
        -sbborder     => 1,        # square bracket border
        -onchange     => undef,    # event handler
	-fg           => -1,
	-bg           => -1,

        %userargs,

        -bindings     => {%bindings},
        -routines     => {%routines},
    
        -focus        => 0,        # value init
        -nocursor     => 1,        # this widget does not use a cursor
    );

    # The windowscr height should be 1.
    $args{-height} = height_by_windowscrheight(1,%args);
    
    # No width given? Then make the width large
    # enough to contain the longest label.
    $args{-width} = width_by_windowscrwidth(
        maxlabelwidth(%args) + 1, 
        -border => 1
    ) unless defined $args{-width};

    my $this = $class->SUPER::new( %args );

    $this->layout;

    if ($Curses::UI::ncurses_mouse) {
	$this->set_mouse_binding('mouse-button1', BUTTON1_CLICKED());
    }


    return $this;
}

sub onChange(;$)  { shift()->set_event('-onchange',  shift()) }

sub layout()
{
    my $this = shift;

    $this->SUPER::layout() or return;

    # Compute the location and length of the listbox.
    my $ll = height_by_windowscrheight(@{$this->{-values}}, -border=>1);
    my $lx = $this->{-x} + $this->{-parent}->{-sx};
    my $ly = $this->{-y} + $this->{-parent}->{-sy} + 1;

    # Don't let the listbox grow out of the screen.
    if ($this->{-y}+$ll > $ENV{LINES}) {
        $ll = $ENV{LINES} - $this->{-y};
    }

    # It's a bit small :-( Can we place it up-side-down?
    my $lim = int($ENV{LINES}/2);
    if ($ll < $lim and ($this->{-sy}+$this->{-y}) > $lim) {
        $ll = height_by_windowscrheight(
            @{$this->{-values}}, 
            -border=>1
        );
        my $y = $this->{-y};
        $y -= $ll - 1;
        if ($y<0)
        {
            $y = 1;
            $ll = $this->{-y};
        }    
        $ly = $y + $this->{-parent}->{-sy} - 1;
    }
        
    # Store the listbox layout setup for later use.

lib/Curses/UI/Popupmenu.pm  view on Meta::CPAN


This sets the onChange event handler for the popupmenu widget.
If a new item is selected, the code in CODEREF will be executed.
It will get the widget reference as its argument.


=back




=head1 METHODS

=over 4

=item * B<new> ( OPTIONS )

=item * B<layout> ( )

=item * B<draw> ( BOOLEAN )

=item * B<intellidraw> ( )

=item * B<focus> ( )

=item * B<onFocus> ( CODEREF )

=item * B<onBlur> ( CODEREF )

These are standard methods. See L<Curses::UI::Widget|Curses::UI::Widget> 
for an explanation of these.

=item * B<get> ( )

This method will return the currently selected value.

=item * B<onChange> ( CODEREF )

This method can be used to set the B<-onchange> event handler
(see above) after initialization of the popupmenu. 

=back




=head1 DEFAULT BINDINGS

There are bindings for the widget itself and bindings
for the popup listbox that can be opened by this widget.

=head2 The widget itself

=over 4

=item * <B<tab>>

Call the 'loose-focus' routine. This will have the widget 
loose its focus.

=item * <B<enter>>, <B<cursor-right>, <B<l>>, <B<space>>

Call the 'open-popup' routine. This will show the 
popup listbox and bring the focus to this listbox. See
B<The popup listbox> below for a description of the bindings 
for this listbox.

=item * <B<cursor-down>>, <B<j>>

Call the 'select-next' routine. This will select the 
item in the list that is after the currently selected
item (unless the last item is already selected). If 
no item is selected, the first item in the list will
get selected. 

=item * <B<cursor-up>>, <B<k>>

Call the 'select-prev' routine. This will select the 
item in the list that is before the currently selected
item (unless the first item is already selected). If 
no item is selected, the first item in the list will
get selected. 

=back 

=head2 The popup listbox

The bindings for the popup listbox are the same as the bindings
for the Listbox widget. So take a look at 
L<Curses::UI::Listbox|Curses::UI::Listbox> for a description
of these. The difference is that the 'loose-focus' and 'option-select'
routine will have the popup listbox to close. If the routine
'option-select' is called, the active item will get selected.


=head1 SEE ALSO

L<Curses::UI>, 
L<Curses::UI::Listbox>
L<Curses::UI::Widget>, 
L<Curses::UI::Common>




=head1 AUTHOR

Copyright (c) 2001-2002 Maurice Makaay. All rights reserved.

Maintained by Marcus Thiesen (marcus@cpan.thiesenweb.de)


This package is free software and is provided "as is" without express
or implied warranty. It may be used, redistributed and/or modified
under the same terms as perl itself.



( run in 0.770 second using v1.01-cache-2.11-cpan-39bf76dae61 )