Audio-Nama
view release on metacpan or search on metacpan
lib/Audio/Nama/Entry.pm view on Meta::CPAN
=item * Delete
Delete one character forwards
=item * Ctrl-Delete
Delete one word forwards
=item * End or Ctrl-E
Move the cursor to the end of the input line
=item * Enter
Accept a line of input by running the C<on_enter> action
=item * Home or Ctrl-A
Move the cursor to the beginning of the input line
=item * Insert
Toggle between overwrite and insert mode
=item * Left
Move the cursor one character left
=item * Ctrl-Left or Alt-B
Move the cursor one word left
=item * Right
Move the cursor one character right
=item * Ctrl-Right or Alt-F
Move the cursor one word right
=back
=cut
=head1 CONSTRUCTOR
=cut
=head2 new
lib/Audio/Nama/Entry.pm view on Meta::CPAN
Takes the following named arguments:
=over 8
=item text => STR
Optional. Initial text to display in the box
=item position => INT
Optional. Initial position of the cursor within the text.
=item on_enter => CODE
Optional. Callback function to invoke when the C<< <Enter> >> key is pressed.
=back
=cut
field $_text :reader :param //= "";
lib/Audio/Nama/Entry.pm view on Meta::CPAN
$self->posttext_render( $rb );
$rb->restore;
}
}
foreach my $line ( $rect->linerange( 1, undef ) ) {
$rb->erase_at( $line, 0, $cols );
}
$self->reposition_cursor;
}
method _recalculate_scroll
{
my ( $pos_ch ) = @_;
my $pos_co = $self->char2col( $pos_ch );
my $off_co = $_scrolloffs_co;
my $pos_x = $pos_co - $off_co;
my $width = $self->window->cols;
my $halfwidth = int( $width / 2 );
# Don't even try unless we have at least 2 columns
return unless $halfwidth;
# Try to keep the cursor within 5 columns of the window edge
while( $pos_x < 5 and $off_co >= 5 ) {
$off_co -= $halfwidth;
$off_co = 0 if $off_co < 0;
$pos_x = $pos_co - $off_co;
}
while( $pos_x > ( $width - 5 ) ) {
$off_co += $halfwidth;
$pos_x = $pos_co - $off_co;
}
return $off_co if $off_co != $_scrolloffs_co;
return undef;
}
method reposition_cursor
{
my ( $pos_ch ) = @_;
$_pos_ch = $pos_ch if defined $pos_ch;
my $win = $self->window or return;
my $new_scrolloffs = $self->_recalculate_scroll( $_pos_ch );
if( defined $new_scrolloffs ) {
$_scrolloffs_co = $new_scrolloffs;
$self->redraw;
}
my $pos_x = $self->char2col( $_pos_ch ) - $_scrolloffs_co;
$win->cursor_at( 0, $pos_x );
}
method _text_spliced
{
my ( $pos_ch, $deleted, $inserted, $at_end ) = @_;
my $win = $self->window;
my $width = $win->cols;
my $insertedlen_co = textwidth $inserted;
lib/Audio/Nama/Entry.pm view on Meta::CPAN
Returns the current entry position, in terms of characters within the text.
=cut
# generated accessor
=head2 set_position
$entry->set_position( $position );
Set the text entry position, moving the cursor
=cut
method set_position
{
my ( $pos_ch ) = @_;
$pos_ch = 0 if $pos_ch < 0;
$pos_ch = length $_text if $pos_ch > length $_text;
$self->reposition_cursor( $pos_ch );
}
=head1 METHODS
=cut
=head2 bind_keys
$entry->bind_keys( $keystr => $value, ... );
lib/Audio/Nama/Entry.pm view on Meta::CPAN
if( defined $value ) {
$_keybindings{$str} = $value;
}
else {
delete $_keybindings{$str};
}
}
}
=head2 make_popup_at_cursor
$win = $entry->make_popup_at_cursor( $top_offset, $left_offset, $lines, $cols );
I<Since version 0.33.>
Creates a new popup window, as if calling L<Tickit::Window/make_popup> on the
widget's main window, but with an offset relative to the current cursor
position.
An offet of (0, 0) will position the popup window's top left corner exactly over
the cursor; this is likely not what you want.
To position the popup just below the widget, use a top offset of +1:
$win = $entry->make_popup_at_cursor( +1, 0, $lines, $cols );
To position the popup just above the widget, use a top offset of negative the
number of lines:
$win = $entry->make_popup_at_cursor( -$lines, 0, $lines, $cols );
=cut
method make_popup_at_cursor
{
my ( $topoff, $leftoff, $lines, $cols ) = @_;
$self->window or
croak "Cannot ->make_popup_at_cursor on an Entry widget with no window";
my $pos_x = $self->char2col( $_pos_ch ) - $_scrolloffs_co;
return $self->window->make_popup( $topoff, $pos_x + $leftoff, $lines, $cols );
}
=head1 TEXT MODEL METHODS
These methods operate on the text input buffer directly, updating the stored
text and changing the rendered display to reflect the changes. They can be
lib/Audio/Nama/Entry.pm view on Meta::CPAN
# Cursor within splice; move to end
$new_pos_ch = $pos_ch + $textlen_ch;
}
# else { ignore }
# No point incrementally updating as we'll have to scroll anyway
unless( defined $new_pos_ch and defined $self->_recalculate_scroll( $new_pos_ch ) ) {
$self->_text_spliced( $pos_ch, $deleted, $text, $at_end );
}
$self->reposition_cursor( $new_pos_ch ) if defined $new_pos_ch and $new_pos_ch != $_pos_ch;
return $deleted;
}
=head2 find_bow_forward
$pos = $entry->find_bow_forward( $initial, $else );
Search forward in the string, returning the character position of the next
beginning of word from the initial position. If none is found, returns
lib/Audio/Nama/Entry.pm view on Meta::CPAN
Search backward in the string, returning the character position of the
previous end of word from the initial position. If none is found, returns
C<undef>.
=cut
method find_eow_backward
{
my ( $pos ) = @_;
my $pretext = substr( $self->text, 0, $pos + 1 ); # +1 to allow if cursor is on the space
return $pretext =~ m/.*\S(?=\s)/ ? $+[0] : undef;
}
## Key binding methods
method key_backward_char
{
if( $_pos_ch > 0 ) {
$self->set_position( $_pos_ch - 1 );
( run in 1.388 second using v1.01-cache-2.11-cpan-39bf76dae61 )