Tk-QuickForm
view release on metacpan or search on metacpan
lib/Tk/QuickForm.pm view on Meta::CPAN
my $self = shift;
my $holder = shift;
my $class = shift;
eval "require $class";
while ($class =~ s/.*[\:\:]//) {}
return $holder->$class(@_);
}
=item B<createForm>
Call this method after you created the B<Tk::QuickForm> widget.
It will create all the pages, sections and entries.
=cut
sub createForm {
my $self = shift;
my @holderstack = ({
offset => 0,
holder => $self,
row => 0,
type => 'root',
});
my $notebook;
my $popcolor;
my $structure = $self->cget('-structure');
my @options = @$structure;
my $labelwidth = 0;
while (@options) {
my $key = shift @options;
if (($key eq '*page') or ($key eq '*section')) {
shift @options;
next;
}
next if ($key eq '*end') or ($key eq '*column') or ($key eq '*expand') or ($key eq '*frame');
my $conf = shift @options;
my $l = length $conf->[1];
unless ($conf->[0] eq 'ext2') { $labelwidth = $l if $l > $labelwidth; }
}
my %options = ();
my %labels = ();
my @padding = (-padx => 2, -pady => 2);
@options = @$structure;
while (@options) {
my $key = shift @options;
if ($key eq '*page') {
my $label = shift @options;
my $holder = $holderstack[0]->{holder};
my $row = $holderstack[0]->{row};
unless (defined $notebook) {
$holder->gridRowconfigure($row, -weight => 1);
$notebook = $holder->NoteBook(
# -borderwidth => 1,
)->grid(
-column => 0,
-row => $row,
-columnspan => 2,
-sticky => 'nsew'
);
$self->{NOTEBOOK} = $notebook;
}
my $page = $notebook->add($label, -label => $label);
my $h = $page->Frame->pack(-fill => 'x');
$h->gridColumnconfigure(1, -weight => 1);
$holderstack[0]->{row} ++;
unshift @holderstack, {
holder => $h,
offset => 0,
row => 0,
type => 'page',
};
} elsif ($key eq '*section') {
my $label = shift @options;
my $h = $holderstack[0];
my $offset = $h->{offset};
my $lf = $h->{holder}->LabFrame(
-label => $label,
-labelside => 'acrosstop',
)->grid(@padding, -column => 0 + $offset, -row => $h->{row}, -columnspan => 2, -sticky => 'nsew');
$lf->gridColumnconfigure(1, -weight => 1);
$holderstack[0]->{row} ++;
unshift @holderstack, {
holder => $lf,
offset => 0,
row => 0,
type => 'section',
};
} elsif ($key eq '*frame') {
my $h = $holderstack[0];
my $offset = $h->{offset};
my $f = $h->{holder}->Frame->grid(@padding,
-column => 0 + $offset,
-row => $h->{row},
-columnspan => 2,
-sticky => 'nsew',
);
$f->gridColumnconfigure(1, -weight => 1);
$holderstack[0]->{row} ++;
unshift @holderstack, {
holder => $f,
offset => 0,
row => 0,
type => 'frame',
};
} elsif ($key eq '*column') {
my $offset = $holderstack[0]->{offset};
$offset = $offset + 2;
$holderstack[0]->{offset} = $offset;
$holderstack[0]->{row} = 0;
my $h = $holderstack[0]->{holder};
$h->gridColumnconfigure(1 + $offset, -weight => 1);
} elsif ($key eq '*end') {
if ($holderstack[0]->{type} eq 'page') {
$notebook = undef
}
if (@holderstack > 1) {
shift @holderstack
} else {
warn "Holder stack is already empty"
}
} elsif ($key eq '*expand') {
my $holder = $holderstack[0]->{holder};
my $row = $holderstack[0]->{row};
my $count = 0;
while (defined $holderstack[$count]) {
my $htype = $holderstack[$count]->{type};
if ($htype eq 'page') {
my $h = $holderstack[$count]->{holder};
$h->packForget;
$h->pack(-expand => 1, -fill => 'both');
last
}
$count ++;
}
$holder->gridRowconfigure($row, -weight => 1);
} else {
my $conf = shift @options;
my @opt = @$conf;
my $type = shift @opt;
my $row = $holderstack[0]->{row};
my $holder = $holderstack[0]->{holder};
my $offset = $holderstack[0]->{offset};
if ($type eq 'color') {
my $file = $self->cget('-colorhistoryfile');
$popcolor = $self->PopColor() unless defined $popcolor;
push @opt, -popcolor => $popcolor, -historyfile => $file;
}
if ($type eq 'ext1') {
my $label = shift @opt;
my $class = shift @opt;
my $l = $holder->Label(
-width => $labelwidth,
-text => $label,
-anchor => 'e'
)->grid(@padding,
-column => 0 + $offset,
-row => $row,
-sticky => 'e'
);
my $w = $self->CreateClass($holder, $class, -quickform => $self, -validatecall => ['validate', $self], @opt);
$w->grid(
-column => 1 + $offset,
-row => $row,
-sticky => 'nsew',
-padx => 2,
-pady => 2
);
$options{$key} = $w;
$labels{$key} = $l;
} elsif ($type eq 'ext2') {
# $label is now actually the reference to the external object
# $values is now actually a boolean scalar to instruct the widget to expand
my $class = shift @opt;
my $w = $self->CreateClass($holder, $class, -validatecall => ['validate', $self], @opt);
$w->grid(
-column => 0,
-row => $row,
-columnspan => 2 + $offset,
-sticky => 'nsew',
-padx => 2,
-pady => 2
);
$options{$key} = $w;
} else {
my $label = shift @opt;
my $l = $holder->Label(
-width => $labelwidth,
-text => $label,
-anchor => 'e'
)->grid(@padding,
-column => 0 + $offset,
-row => $row, -sticky => 'e'
);
my $t = $self->{TYPES}->{$type};
my @o = @$t;
my $class = shift @o;
my %opthash = (@o);
while (@opt) {
my $key = shift @opt;
my $value = shift @opt;
$opthash{$key} = $value;
}
$opthash{'-validatecall'} = ['validate', $self];
my $img = $opthash{'-image'};
if ((defined $img) and ($img =~ /^-/)) {
$opthash{'-image'} = $self->cget($img)
}
if (exists $opthash{'-values'}) {
my $values = $opthash{'-values'};
if ((ref $values) and ($values =~/^CODE/)) {
my @vals = &$values;
$opthash{'-values'} = \@vals;
}
}
my $widg = $self->CreateClass($holder, $class, %opthash, -quickform => $self)->grid(
-column => 1 + $offset,
-row => $row,
-sticky => 'nsew',
-padx => 2, -pady => 2
);
$options{$key} = $widg;
$labels{$key} = $l;
$holderstack[0]->{row} ++;
}
}
}
$self->{OPTIONS} = \%options;
$self->{LABELS} = \%labels;
$self->{NOTEBOOK} = $notebook;
$self->after(10, ['validate', $self]);
return $notebook;
}
sub DefineTypes {
my $self = shift;
( run in 0.543 second using v1.01-cache-2.11-cpan-e1769b4cff6 )