Curses-UI-Grid

 view release on metacpan or  search on metacpan

examples/grid-demo.pl  view on Meta::CPAN

];


$cui->add('menu', 'Menubar', -menu => $menu);


# ----------------------------------------------------------------------
# Setup bindings and focus
# ----------------------------------------------------------------------

sub goto_next_demo()
{
    $current_demo++;
    $current_demo = 3 if $current_demo > 3;
    $w{$current_demo}->focus;
}


sub goto_prev_demo()
{
    $current_demo--;
    $current_demo = 1 if $current_demo < 1;
    $w{$current_demo}->focus;
}


# Bind <CTRL+Q> to quit.
$cui->set_binding( sub{ exit }, "\cQ" );
$cui->set_binding( \&goto_next_demo, "\cN" );
$cui->set_binding( \&goto_prev_demo, "\cP" );

# Bind <CTRL+X> to menubar.
$cui->set_binding( sub{ shift()->root->focus('menu') }, "\cX" );





sub select_demo($;)
{
    my $nr = shift;
    $current_demo = $nr;
    $w{$current_demo}->focus;
}

sub fill_data($;) {
my $offset=shift;
my $limit=shift;
my $data=shift;
my $grid=shift;

    for my $i (0 .. $limit) {
          my $row=$grid->get_row( $grid->{_rows}[$i+1] );
	  next unless ref($row);

	  if($#{$data} <= $offset+$i) {

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

    $this->{-page};
}


=item page_size

Sets/gets page size.

=cut

sub page_size($;)  { 
    my ($this, $page_size) = @_;
    $this->{-page_size} = $page_size 
      if(defined $page_size);
    $this->{-page_size};
}


=back

=head3 Layout methods

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

}


=item clear_vline

Clears vertcal lines position.

=cut


sub clear_vline() {
    my $this = shift;
    $this->vertical_lines([]);
}


=item focus_row( ROW, FORCE, DIRECTION )

Moves focus to passed in row.

=cut

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

=head3 Colors methods

=over

=item set_color( BG_COLOR, FG_COLOR, CANVAS )

Sets color for passed in canvaed object. Returns color pair.

=cut

sub set_color($;) {
    my ($this, $bg, $fg, $canvas) = @_;
    return 
      unless ref($canvas);
    $bg ||= -1;
    $fg ||= -1;
    return 
      if($fg eq '-1' || $bg eq '-1');

    my $color_pair;
    if($Curses::UI::color_support && $bg && $fg) {

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

}


=item grid_pagedown( BOOLEAN )

Calls grid onnextpage event.
Redraws immediate grid if passed in value is TRUE.

=cut

sub grid_pagedown($;) {
    my ($this, $do_draw) = @_;
    $this->run_event('-onnextpage', $this)
      or return;
    $this->draw(1) 
      if $do_draw;
    $this->focus_row($this->get_foused_row, 1, 0) 
      if ($do_draw && $do_draw != 1);
    $this;
}

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

  $text = $alignlign eq 'L' 
    ? substr($text, 0, $current_width) 
    : substr($text, (length($text) - $current_width), $current_width);
  $text .= ' '
    if(ref($this->row) && $this->row->type ne 'data');
	
  $text;
}


sub draw($;) {
    my $this = shift;
    my $no_doupdate = shift || 0;

    # Return immediately if this object is hidden.
    return $this if $this->hidden;
    return $this if $Curses::UI::screen_too_small; 
     my $grid =$this->parent;
     my $row=$this->row(1);

   if( $#{$grid->{_rows}} > 1 ) {

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

     $row->canvasscr->attroff(A_BOLD) if($row->{-focus});
     doupdate() if ! $no_doupdate && ! $grid->test_more;
     $row->canvasscr->move($row->y,$this->xabs_pos);
     $row->canvasscr->noutrefresh;


    return $this;
}    


sub draw_cell($$$) {
    my $this = shift;
    my $no_doupdate = shift || 0;
    my $row = shift;
    $row = $this->row($row);
    return $this 
      if $this->hidden;
    my $grid = $this->parent;
    
    $grid->run_event('-oncelldraw', $this)
      if ($row->type ne 'head');

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

    my $pair=$grid->set_color($fg,$bg,$row->canvasscr);
    my $x = $this->x;
    my $text = $this->layout_text || '';
    $text = substr($text, 0, $grid->canvaswidth - $x) 
      if (length($text) + $x >= $grid->canvaswidth);
    $row->canvasscr->addstr($row->y, $x, $text);
    $grid->color_off($pair, $row->canvasscr);
    $this;
}

sub text($$) {
    my $this = shift;
    my $text = shift;
    my $result='';
    my $row=$this->row;
    my $grid =$this->parent;
    my $type= $row->type || '';
    my $id=$this->id;
    #if row type is head return or set label attribute otherwise cell value
    if(defined $text) {
	if($type eq 'head') { 
	   $this->{-label}=$text; 
	} else {  
	   $row->{-cells}{$id}=$text; 
	}
    }
    
    $result = $type eq 'head' ? $this->{-label} : exists $row->{-cells}{$id} ? $row->{-cells}{$id} :'' if($type) ;
    return $result;
}

sub cursor_right($) {
    my $this = shift;
    $this->overwriteoff;
    $this->xoffset($this->xoffset-1) if($this->xpos()   == ($this->current_width -1) );
    $this->xpos($this->xpos+1);
    $this->draw(1);
    
    return $this;																	        return $this;	    
}

sub cursor_left($) {
    my $this = shift;
    $this->overwriteoff;
    $this->xoffset($this->xoffset+1) unless($this->xpos($this->xpos));
    $this->xpos($this->xpos-1);
    $this->draw(1);
    return $this;	    
}

sub cursor_to_home($) {
    my $this = shift;
    $this->overwriteoff;
    my $text = $this->text;
    my $current_width = $this->current_width;
    my $align = $this->align;
    
    $this->xoffset($align eq 'L' 
      ?  $current_width 
      : (length($text) - $current_width > 0 
        ? length($text) - $current_width

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

    );

    $this->xpos($align eq 'L' 
      ? 0 
      : $current_width - length($text)
    );
    $this->draw(1);
}


sub cursor_to_end($) {
    my $this = shift;
    $this->overwriteoff;
    my $text_lenght = length $this->text;
    my $current_width = $this->current_width;
    my $align = $this->align;
    $current_width = $current_width > $text_lenght && $align eq 'L' 
      ? $text_lenght + 1 
      : $current_width;
    $this->xoffset(
      $align eq 'R' 

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

        : $current_width -  $text_lenght - 1) 
          if ($text_lenght >= $current_width);
    
    $this->xpos($align eq 'L' 
      ? $current_width - 1 
      : $current_width-1);
    
    $this->draw(1);
}

sub delete_character($) {
    my $this = shift;
    return if $this->readonly;
    my $ch = shift;
    my $grid = $this->parent;
    $grid->run_event('-oncellkeypress', $this, $ch) 
      or return;
    $this->overwriteoff;
    my $text=$this->text;
    my $xo = $this->xoffset;
    my $pos = $this->text_xpos;

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN


    return if($align eq 'R' && $pos <= 0);  
    $this->xoffset($this->xoffset-1) if($align eq 'R' &&  $xo && length($text) - $xo >= $current_width);
    $this->xoffset($this->xoffset-1) if($align eq 'L' && length($text) > $len);
    $pos-- if($align eq 'R');
    substr($text, $pos, 1, '') if(abs($pos) <= length($text));
    $this->text($text);
    $this->draw(1);
}

sub backspace($) {
    my $this = shift;
    my $ch = shift;
    return if $this->readonly;
    my $grid =$this->parent;
    $grid->run_event('-oncellkeypress', $this, $ch) 
      or return;
    $this->overwriteoff;
    my ($align,$xo)=($this->align,$this->xoffset);
    $this->cursor_left;
    $this->delete_character();
    $this->cursor_right  if($align eq 'R' );
}

sub add_string($$;) {
    my $this = shift;
    my $ch = shift;
    return if $this->readonly;
    my $grid = $this->parent;

    my $ret= $grid->run_event('-oncellkeypress', $this, $ch)
      or return;

    my @ch = split //, $ch;
    $ch = '';

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

    substr($text, abs($pos) , 0) = $ch  if($pos <= $len );
    $this->text($text);
    $this->cursor_right if($align eq 'L');
    $this->draw();
    $grid->run_event('-onaftercellkeypress', $this, $ch);
}



# x of cell
sub x($;) {
    my $this=shift;
    my $x=shift;
    $this->{-x}=$x if(defined $x);
    return $this->{-x};
}

# absolute x position to row
sub xabs_pos($;) {
    my $this=shift;
    my $result="";
    my $xpos=( $this->xpos > ($this->current_width-1) ? $this->current_width-1 : $this->xpos );
    $xpos =0 if($xpos < 0);
    return $this->{-x} + $xpos;
}


# cursor relative x pos
sub xpos($;) {
    my $this=shift;
    my $x=shift;
    if(defined $x){ 
	$x = 0 if($x < 0);
	$x= $this->width-1 if($x > $this->width-1 );
        $this->{-xpos}=$x;
    }
    return $this->{-xpos};
}


# cursor position in text
sub text_xpos($;) {
    my $this=shift;
    my ($w,$x,$xo,$align,$l)=($this->current_width-1,$this->xpos,$this->xoffset,$this->align,length($this->text));    
    return  $align eq 'R' ? $l-($w-$x+abs($xo)) : $x-$xo;
}


# offset to x pos
sub xoffset($;) {
    my $this=shift;
    my $xo=shift;
    my ($align,$l,$w)=($this->align,length(($this->text || '')),$this->current_width);

    if( defined($xo) ) {
	if($align eq 'L' ) {
        $xo=0 if($xo > 0);
        #$xo=$this->w-1 if($xo < 0);
	} else {
	    $xo=$l-$w if($xo > ($l-$w) && $xo);

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

	}


	$this->{-xoffset}=$xo;
    }
    return $this->{-xoffset};
}


# event of focus
sub event_onfocus()
{
    my $this = shift;
    my $grid =$this->parent;
    $this->overwriteon;
    $grid->{-cell_idx}=$grid->{-cellid2idx}{ $this->{-id} };

    # Store value of cell in case of data change
    if(ref($this->row) && $this->row->type ne 'head' ) {
	$this->row->set_undo_value($this->id,$this->text);
    }

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

    }

    $this->xpos($this->align eq 'L' ? 0 : $this->current_width - 1);
    $this->xoffset(0);
    $grid->run_event('-oncellfocus', $this);
    $this->draw(1);
    return $this;
}


sub event_onblur() {
    my $this = shift;
    my  $grid =$this->parent;
    $this->xpos($this->align eq 'L' ? 0 : $this->current_width - 1);
    $this->xoffset(0);
    $grid->run_event('-oncellblur',$this)
      or return;
    
    if (ref($this->row) && $this->row->type ne 'head' ) {
				my $undo = $this->row->get_undo_value($this->id);
				my $text = $this->text;

lib/Curses/UI/Grid/Cell.pm  view on Meta::CPAN

	    	    if ($undo || '') ne ($text || '');
    }
    
    $grid->{-cell_idx_prev} = $grid->{-cellid2idx}{$this->{-id}};
    $this->{-focus} = 0;

    $this->draw;
    $this;
}

sub overwriteoff() { shift()->{-overwritetext}=0 }
sub overwriteon() { shift()->{-overwritetext}=1 }


sub overwritetext($;) {
    my $this=shift;
    my $result=!$this->{-overwrite} ? $this->{-overwrite}  : $this->{-overwritetext};
    $this->overwriteoff();
    return $result;
}

sub has_focus() {
    my $this=shift;
    my $grid =$this->parent;
    my $result=0;
    $result=1 if($this->{-focus});
return $result;
}


sub focus($;) {
    my $this=shift;
    # Let the parent focus this object.
    my $parent = $this->parent;
    $parent->focus($this) if defined $parent;
    $this->draw(1);
    return $this;
}


sub bg() {
    my $this = shift;
    my $bg=shift;
    $this->{-bg_}=$bg if(defined $bg);
    return  $this->{-bg_} ? $this->{-bg_} : exists( $this->{-bg} ) && $this->{-bg} ? $this->{-bg} : $this->row->bg;
}

sub fg() {
    my $this = shift;
    my $fg=shift;
    $this->{-fg_}=$fg if(defined $fg);
    return  $this->{-fg_} ? $this->{-fg_} : exists( $this->{-fg} ) && $this->{-bg} ? $this->{-fg} : $this->row->fg;
}

sub row() {
    my ($this, $row) = @_;
    $this->{-row} = $row 
      if defined $row;
    $this->{-row} = $this->parent->get_foused_row
	    if(!ref($this->{-row}) ||  ref($this->{-row}) ne 'Curses::UI::Grid::Row');
    return $this->{-row};
}



sub align()  { uc(shift()->{-align})    }
sub frozen() { shift->{-frozen}         }
# defined width
sub width()  { 
		my ($self, $width) = @_;
		$self->{-width} = $width if(defined $width);
		$self->{-width};
}

#current width
sub current_width {
    my ($this, $current_width) = @_;
    $this->{-current_width} = $current_width 
      if (defined $current_width);

lib/Curses/UI/Grid/Row.pm  view on Meta::CPAN

}



sub layout_content {
   my $this = shift;
   return $this;
}


sub layout_row($;){
    my $this = shift;
    my $p=$this->parent;
    my $c=\@{ $p->{_cells} };
    my $text = '';
    my $w = $p->canvaswidth;
    
    for my $i ( 0 ..    $#{$c} ) {
				my $cell = $p->id2cell($$c[$i]);
				$text .=  ($cell->layout_text() || '')
				. ' '
				  unless $cell->hidden;
    }
    $text = substr(sprintf("%-" . $w . "s", $text), 0, $w);
}


sub draw(;$) {
    my $this = shift;
    my $no_doupdate = shift || 0;
    my $grid = $this->parent;
    return $this if $Curses::UI::screen_too_small;
    return $this if $this->hidden;
    $this->layout_row;
    $this->draw_row($no_doupdate);
    doupdate() if ! $no_doupdate && ! $grid->test_more;
    return $this;
}    



sub draw_row(;$) {
    my $this = shift;
    my $no_doupdate = shift || 0;

    # Return immediately if this object is hidden.
    return $this if $this->hidden;


    my $p=$this->parent();
    $this->canvasscr->attron(A_BOLD) if($this->{-focus});

lib/Curses/UI/Grid/Row.pm  view on Meta::CPAN

		foreach my $x (@{$grid->vertical_lines}) {
	      $this->canvasscr->move($this->y,$x);
        $this->canvasscr->vline(ACS_VLINE,1);	    
		}
    
    $grid->color_off($pair, $this->canvasscr);
		$this;
}


sub bg() {
    my $this = shift;
    my $bg= shift;
    $this->{-bg_}=$bg if(defined $bg);
    return  $this->{-bg_} ? $this->{-bg_} : exists( $this->{-bg} ) ? $this->{-bg} : $this->parent()->{-bg};
}

sub fg() {
    my $this = shift;
    my $fg= shift;
    $this->{-fg_}=$fg if(defined $fg);
    return  $this->{-fg_} ? $this->{-fg_} :exists( $this->{-fg} ) ? $this->{-fg} : $this->parent()->{-fg};
}

sub event_onfocus() {
    my $this = shift;
    my $p=$this->parent;
    return $p->focus($this) unless($this->focusable);
    # Let the parent find another widget to focus
    # if this widget is not focusable.
    $this->{-focus} = 1;
    $p->run_event('-onrowfocus',$this);
    $p->{-row_idx}=$p->{-rowid2idx}{ $this->{-id} };
    # clear date change info
    $this->{-cell_undo} = {};
    $this->draw(1);
        my $cell = $p->get_foused_cell;
           $cell->event_onfocus if (defined $cell);
    return $this;
}

sub event_onblur() {
    my $this = shift;
    my $p=$this->parent;

    #check if data row was changed
    my $changed=0;
    for my $k (keys %{ $this->{-cell_undo} } ) {
	 if( $this->{-cell_undo}{$k} ne $this->{-cell}{$k} ) {
	    $changed=1;
	    last;
	}

lib/Curses/UI/Grid/Row.pm  view on Meta::CPAN

        	return '';
    	    }
	}
    $this->{-focus} = 0;
    $p->{-row_idx_prev}=$p->{-rowid2idx}{ $this->{-id} };
    $this->draw;
    return $this;
}

# y position of row
sub y(){
    my $this = shift;
    return $this->{-y} ? $this->{-y} +1:$this->{-y};
}

sub type(){ shift()->{-type}; }

sub set_value($;) {
    my $this = shift;
    my $cell = shift;
    my $data = shift;
    my $cell_id=ref($cell) ? $cell->{-id} : $cell;
    $this->{-cells}{$cell_id}=$data;
    $this->draw if($this->{-focus});
}


sub set_values($;) {
    my $this = shift;
    my %data = @_;
    if(defined $this->{-cells} ) {
      $this->{-cells}={ %{$this->{-cells}} , %data } ;
    } else {     $this->{-cells}={ %data } ;}


    $this->draw if($this->{-focus});
}


sub set_undo_value($;) {
    my $this = shift;
    my $cell = shift;
    my $data = shift;
    my $cell_id=ref($cell) ? $cell->{-id} : $cell;
    $this->{-cells_undo}{$cell_id}=$data;
}

sub get_undo_value($;) {
    my $this = shift;
    my $cell = shift;
    my $result='';
    my $cell_id=ref($cell) ? $cell->{-id} : $cell;
    $result= $this->{-cells_undo}{$cell_id} if(exists($this->{-cells}{$cell_id}));
    return $result;
}



sub get_value($;) {
    my $this = shift;
    my $cell = shift;
    my $cell_id=ref($cell) ? $cell->{-id} : $cell;
    return $this->{-cells}{$cell_id};
}

sub get_values($;) {
    my $this = shift;
    return %{ $this->{-cells} };
}

sub get_values_ref($;) {
    my $this = shift;
    return \%{  $this->{-cells} };
}


sub cleanup {
    my $this = shift;
    my $grid = $this->parent or return;		
    delete $grid->{-rowid2idx}{$this->id};
    delete $grid->{-id2row}{$this->id};
    $grid->{-rows}--;
    $this->{$_} = ''
    for (qw(-canvasscr -parent));
}


sub DESTROY($;) {
    my $this = shift;
    $this->cleanup;
}

1;

__END__

=pod



( run in 0.328 second using v1.01-cache-2.11-cpan-1f129e94a17 )