Alt-Tickit-Widgets-ObjectPad

 view release on metacpan or  search on metacpan

Build.PL  view on Meta::CPAN

   requires => {
      'perl' => '5.010',
      'List::Util' => '1.33',
      'Object::Pad' => '0.09',
      'Parser::MGC' => 0,
      'Struct::Dumb' => 0,
      'Syntax::Keyword::Dynamically' => 0,
      'Tickit::Event' => '0.63',
      'Tickit::RenderBuffer' => 0,
      'Tickit::Utils' => '0.29',
      'Tickit::Window' => '0.57', # $win->bind_event
   },
   test_requires => {
      'Test::Identity' => 0,
      'Test::More' => '0.88', # done_testing
      'Test::Refcount' => 0,
   },
   destdir => ( $alt ? $alt eq 'OVERWRITE' ? '' : $alt : 'no-install-alt' ),
   license => 'perl',
   create_license => 1,
   create_readme  => 1,

Changes  view on Meta::CPAN

           its own (WINDOW_XS branch)

0.25    2017/02/04 14:54:12
        [CHANGES]
         * Minor edits to unit tests to pass on Tickit post-0.61
           (WINDOW_XS branch)

0.24    2016/08/08 13:43:01
        [CHANGES]
         * Tickit 0.57 deprecations:
            + Use $win->bind_event instead of $win->set_on_*

        [BUGFIXES]
         * Ensure that Tickit::Widget::Box can cope with removing its child or
           window
         * Ensure that construction-time child proportion works on
           Tickit::Widget::Box

0.23    2016/05/10 17:51:02
        [CHANGES]
         * Prepare for Tickit 0.56 deprecations:

lib/Tickit/Widget.pm  view on Meta::CPAN


our $VERSION = '0.53';

use Carp;
use Scalar::Util qw( weaken );
use List::Util 1.33 qw( all );

use Tickit::Pen;
use Tickit::Style;
use Tickit::Utils qw( textwidth );
use Tickit::Window 0.57;  # $win->bind_event
use Tickit::Event 0.63;  # $info->type("newapi") on Focus

use constant PEN_ATTR_MAP => { map { $_ => 1 } @Tickit::Pen::ALL_ATTRS };

use constant KEYPRESSES_FROM_STYLE => 0;

use constant CAN_FOCUS => 0;

=head1 NAME

lib/Tickit/Widget.pm  view on Meta::CPAN

sub window_gained
{
   my $self = shift;

   my $window = $self->window;

   weaken $self;

   my $event_ids = $self->{event_ids} //= {};

   $event_ids->{geomchange} = $window->bind_event( geomchange => sub {
      $self->reshape;
      $self->redraw if !$self->parent;
   } );

   $event_ids->{expose} = $window->bind_event( expose => sub {
      my ( $win, undef, $info ) = @_;
      $win->is_visible or return;

      $info->rb->setpen( $self->{pen} );

      $self->render_to_rb( $info->rb, $info->rect );
   });

   $event_ids->{focus} = $window->bind_event( focus => sub {
      my ( $win, undef, $info ) = @_;
      $self->_on_win_focus( $win, $info->type( "newapi" ), $info->win );
   } ) if $self->can( "_widget_style_type" );

   if( $self->can( "on_key" ) or $self->KEYPRESSES_FROM_STYLE ) {
      $event_ids->{key} = $window->bind_event( key => sub {
         my ( $win, undef, $info ) = @_;

         {
            # Space comes as " " but we'd prefer to use "Space" in styles
            my $keystr = $info->str eq " " ? "Space" : $info->str;

            my $action;
            $action = $self->get_style_values( "<$keystr>" ) if $self->KEYPRESSES_FROM_STYLE;
            $action //= "focus_next_after"  if $keystr eq "Tab";
            $action //= "focus_next_before" if $keystr eq "S-Tab";

lib/Tickit/Widget.pm  view on Meta::CPAN

            last unless $action;

            my $code = $self->can( "key_$action" );
            return 1 if $code and $code->( $self, $info );
         }
         my $code = $self->can( "on_key" );
         return 1 if $code and $code->( $self, $info );
      } );
   }

   $event_ids->{mouse} = $window->bind_event( mouse => sub {
      my ( $win, undef, $info ) = @_;
      $self->take_focus if $self->CAN_FOCUS and $info->button == 1 and $info->type eq "press";
      $self->on_mouse( $info ) if $self->can( "on_mouse" );
   } );
}

sub _on_win_focus
{
   my $self = shift;
   my ( $win, $focus ) = @_;

lib/Tickit/Widget.pm  view on Meta::CPAN

   $self->parent and $self->parent->focus_next( before => $self );
   return 1;
}

sub window_lost
{
   my $self = shift;

   my $window = $self->window;

   $window->unbind_event_id( $_ ) for values %{ $self->{event_ids} };
}

=head2 window

   $window = $widget->window

Returns the current window of the widget, if one has been set using
C<set_window>.

=cut

lib/Tickit/Widget/Entry.pm  view on Meta::CPAN

Optional. Callback function to invoke when the C<< <Enter> >> key is pressed.

=back

=cut

has $_text;
has $_pos_ch;
has $_scrolloffs_co = 0;
has $_overwrite     = 0;
has %_keybindings;
has $_on_enter;

method BUILD
{
   my %params = @_;

   $_text = defined $params{text} ? $params{text} : "";
   $_pos_ch = defined $params{position} ? $params{position} : 0;

   my $textlen = length $_text;
   $_pos_ch = $textlen if $_pos_ch > $textlen;

   # TODO: It'd be nice to get this out of Object::Pad but it's a list on a
   #   hash and thus not const
   %_keybindings = (
      'C-a' => "key_beginning_of_line",
      'C-e' => "key_end_of_line",
      'C-k' => "key_delete_line",
      'C-u' => "key_backward_delete_line",
      'C-w' => "key_backward_delete_word",

      'M-b' => "key_backward_word",
      'M-f' => "key_forward_word",

      'Backspace'   => "key_backward_delete_char",

lib/Tickit/Widget/Entry.pm  view on Meta::CPAN


method on_key
{
   my ( $args ) = @_;

   return 0 unless $self->window->is_focused;

   my $type = $args->type;
   my $str  = $args->str;

   if( $type eq "key" and my $code = $_keybindings{$str} ) {
      $self->$code( $str );
      return 1;
   }
   if( $type eq "text" ) {
      $self->on_text( $str );
      return 1;
   }

   return 0;
}

lib/Tickit/Widget/Entry.pm  view on Meta::CPAN

   $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 $entry->bind_keys( $keystr => $value, ... )

Associate methods or CODE references with keypresses. On receipt of a the key
the method or CODE reference will be invoked, being passed the stringified key
representation and the underlying C<Term::TermKey::Key> structure.

 $ret = $entry->method( $keystr, $key )
 $ret = $coderef->( $entry, $keystr, $key )

This method takes a hash of keystring/value pairs. Binding a value of C<undef>
will remove it.

=cut

method bind_keys
{
   while( @_ ) {
      my $str   = shift;
      my $value = shift;

      if( defined $value ) {
         $_keybindings{$str} = $value;
      }
      else {
         delete $_keybindings{$str};
      }
   }
}

=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
used by a program to directly manipulate the text.

lib/Tickit/Widget/Entry.pm  view on Meta::CPAN

Returns the currently entered text.

=cut

method text { $_text }

=head2 $entry->set_text( $text )

Replace the text in the entry box. This completely redraws the widget's
window. It is largely provided for initialisation; for normal edits (such as
from keybindings), it is preferable to use C<text_insert>, C<text_delete> or
C<text_splice>.

=cut

method set_text
{
   my ( $text ) = @_;

   $_text = $text;
   $_pos_ch = length $text if $_pos_ch > length $text;

lib/Tickit/Widget/Entry.pm  view on Meta::CPAN


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 );
   }
}

method key_backward_delete_char
{



( run in 0.589 second using v1.01-cache-2.11-cpan-2398b32b56e )