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