###############################################################################
# subclass of Curses::UI::Row is a widget that can be used to display
# and manipulate row in grid model
#
# (c) 2004 by Adrian Witas. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the same terms as perl itself.
###############################################################################
package Curses::UI::Grid::Row;
use strict;
use Curses;
use Curses::UI::Common;
use Curses::UI::Grid;
use vars qw(
$VERSION
@ISA
);
$VERSION = '0.01';
@ISA = qw(
Curses::UI::Grid
);
sub new ()
{
my $class = shift;
my %userargs = @_;
keys_to_lowercase(\%userargs);
my %args = (
# Parent info
-parent => undef # the parent object
# Position and size
,-y => 0 # vertical position (rel. to -window)
# Grid model
,-focusable => 1
,-type => undef # row type: head,data
,-cells => undef # data cell
,-cells_undo => {} # holds data chaned
,-bg_ => undef # user defined background color
,-fg_ => undef # user defined font color
,%userargs
);
# Create the Row
my $this = {%args,-canvasscr=>$args{-parent}->{-canvasscr}};
bless $this;
return $this;
}
sub layout {
my $this = shift;
$this->layout_row;
return $this;
}
sub layout_content {
my $this = shift;
return $this;
}
sub layout_row($;){
my $this = shift;
my $p=$this->parent;
my $c=\@{ $p->{_cells} };
my ($text,$w)=("",$p->canvaswidth);
for my $i ( 0 .. $#{$c} ) {
my $o=$p->id2cell($$c[$i]);
$text.=$o->layout_text()." " unless $o->hidden;
}
$text=substr( sprintf("%-".$w."s" ,$text),0,$w);
return $text;
}
sub draw(;$) {
my $this = shift;
my $no_doupdate = shift || 0;
return $this if $Curses::UI::screen_too_small;
return $this if $this->hidden;
$this->layout_row;
$this->draw_row($no_doupdate);
doupdate() unless $no_doupdate;
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});
$p->run_event('-onrowdraw',$this);
# Let there be color for data cell
# for header grid's colors
my $fg=($this->type ne 'head') ? $this->fg : $p->{-fg} ;
my $bg=($this->type ne 'head') ? $this->bg : $p->{-bg} ;
my $pair=$p->set_color($fg,$bg,$this->{-canvasscr});
my $c=\@{ $p->{_cells} };
for my $i(0 .. $#{$c} ) {
$p->id2cell( $$c[$i] )->draw_cell(1,$this);;
}
$this->{-canvasscr}->attroff(A_BOLD) if($this->{-focus});
$p->color_off($pair,$this->{-canvasscr});
$this->draw_vline() if($this->type ne "head");
$this->{-canvasscr}->noutrefresh;
return $this;
}
#draw certical line
sub draw_vline(;$) {
my $this = shift;
my $p=$this->parent;
my $pair=$p->set_color( $p->{-bfg} ne "-1" ? $p->{-bfg} :$p->{-fg},$this->bg,$this->{-canvasscr});
foreach my $x (@{ $p->{-vlines} }) {
$this->{-canvasscr}->move($this->y,$x);
$this->{-canvasscr}->vline(ACS_VLINE,1);
}
$p->color_off($pair,$this->{-canvasscr});
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->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->getfocuscell;
$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;
}
}
if($changed) {
my $ret= $p->run_event('-onrowchange',$this);
#if event return values and it's equal 0 then cancell onblur event
if(defined $ret) {
if($ret eq "0") {
return '';
}
}
}
#If the Container loose it focus
#the current focused child must be unfocused
my $cell = $this->parent->getfocuscell;
#test if current row can be unfocused otherwise cancel current event
if(defined $cell) {
my $ret = $cell->event_onblur();
return 0 if(defined $ret && !$ret);
}
my $ret=$p->run_event('-onrowblur',$this);
if(defined $ret) {
if($ret eq "0") {
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 DESTROY($;) {
my $this = shift;
# clear references
foreach my $k (qw(-canvasscr -parent)) {
$this->{$k}='';
}
foreach my $k( keys %{$this} ) {
delete $this->{$k};
}
}
1;
__END__
=pod
=head1 NAME
Curses::UI::Grid::Row
Create and manipulate row in grid model.
=head1 CLASS HIERARCHY
Curses::UI::Grid
|
+----Curses::UI::Row
=head1 SYNOPSIS
use Curses::UI;
my $cui = new Curses::UI;
my $win = $cui->add('window_id', 'Window');
my $grid =$win->add('mygrid','Grid' );
my $row1=$grid->add_row( -fg=>'blue'
,-bg->'white' );
=head1 DESCRIPTION
Curses::UI::Grid::Row is a widget that can be used to
manipulate row in grid model
See exampes/grid-demo.pl in the distribution for a short demo.
=head1 STANDARD OPTIONS
-parent,-fg,-bg
=head1 WIDGET-SPECIFIC OPTIONS
=over 4
=item * B<-cells> < HASH >
=item * B<-cells_undo> < HASH >
=back
=head1 METHODS
=over 4
=item * B<new> ( OPTIONS )
Constructs a new grid object using options in the hash OPTIONS.
=item * B<layout> ( )
Lays out the row object with cells, makes sure it fits
on the available screen.
=item * B<draw> ( BOOLEAN )
Draws the grid object along with cells. If BOOLEAN
is true, the screen is not updated after drawing.
By default, BOOLEAN is true so the screen is updated.
=back
=head1 WIDGET-SPECIFIC OPTIONS
=over 4
=item * B<layout_row> ( )
Lays out the row with cells, makes sure it fits
on the available screen.
=item * B<draw_row> ( BOOLEAN )
Draws the row object along with cells. If BOOLEAN
is true, the screen is not updated after drawing.
By default, BOOLEAN is true so the screen is updated.
=item * B<set_value> ( CELL , VALUE )
This routine will set value for given cell.
CELL could by either cell object or id cell.
=item * B<set_values> ( HASH )
This routine will set values for cells.
HASH should contain cells id as keys.
This method will not affect cells which are not given in HASH.
=item * B<get_value> ( CELL )
This routine will return value for given cell.
CELL could by either cell object or id cell.
=item * B<get_values> ( )
This routine will return HASH values for row cells.
HASH will be contain cells id as keys.
=item * B<get_values_ref> ( )
This routine will return HASH reference for given row values.
=item * B<fg> ( COLOR )
This routine could set or get foreground color using -fg_ option .
If -fg_ is NULL then -fg or parent fg color is return.
=item * B<bg> ( COLOR )
This routine could set or get background color using -bg_ option.
If -bg_ is NULL then -bg or parent bg color is return.
=item * B<text> ( TEXT )
This routine will set or get value for cell and active row.
=back
=head1 SEE ALSO
Curses::UI::Grid::Cell Curses::UI::Grid
=head1 AUTHOR
Copyright (c) 2004 by Adrian Witas. All rights reserved.
=head1 COPYRIGHT AND LICENSE
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=pod SCRIPT CATEGORIES
User Interfaces