Tk-FormUI
view release on metacpan or search on metacpan
lib/Tk/FormUI.pm view on Meta::CPAN
sub show_once
{
my $self = shift;
my $parent = shift;
my $test = shift;
my $win; ## Window widget
my $result; ## Variable used to capture the result
## Create the window
if ($parent)
{
## Create as a TopLevel to the specified parent
$win = $parent->TopLevel(-title => $self->title);
}
else
{
## Create as a new MainWindow
$win = MainWindow->new(-title => $self->title);
}
## Hide the window
$win->withdraw;
## Do not allow user to resize
$win->resizable(0,0);
## Now use the grid geometry manager to layout everything
my $grid_row = 0;
## See if we have a message
if ($self->message)
{
## Leave space for the message and a spacer
## but wait to create the widget
$grid_row = 2;
}
my $first_field;
## Now add the fields
foreach my $field (@{$self->fields})
{
## See if the widget was created
if (my $widget = $field->build_widget($win))
{
## See if there's an error
my $err = $field->error;
if ($err)
{
## Display the error message
$win->Label(
-text => $err,
-font => $self->error_font,
-anchor => qq{w},
-justify => qq{left},
-foreground => $self->error_font_color,
)
->grid(
-row => $grid_row++,
-rowspan => 1,
-column => 0,
-columnspan => 2,
-sticky => qq{w},
);
}
## Create the label
my $label = $field->build_label($win);
## See if there's an error
if ($err)
{
## Update the field's label to use the error marker, font,
## and font color
$label->configure(
-text => $self->error_marker . qq{ } . $field->label . qq{:},
-font => $self->error_font,
-foreground => $self->error_font_color,
);
}
## Place the label
$label->grid(
-row => $grid_row,
-rowspan => 1,
-column => 0,
-columnspan => 1,
-sticky => qq{ne},
);
## Place the widget
$widget->grid(
-row => $grid_row,
-rowspan => 1,
-column => 1,
-columnspan => 1,
-sticky => qq{w},
);
## Increment the row index
$grid_row++;
## See if this is our first non-readonly field
if (!$first_field && !$field->readonly)
{
$first_field = $field;
}
}
}
## Use an empty frame as a spacer
$win->Frame(-height => 5)->grid(-row => $grid_row++);
## Create the button
my $button_text = $self->button_label;
my $underline = index($button_text, qq{&});
$button_text =~ s/\&//gx; ## Remove the &
$win->Button(
-text => $button_text,
-font => $self->button_font,
-width => length($button_text) + 2,
-command => sub {$result = 1;},
-underline => $underline,
)
->grid(
-row => $grid_row++,
-rowspan => 1,
-column => 0,
-columnspan => 2,
-sticky => qq{},
);
## Set the form's message
$self->_set_message($win);
$self->_watch_variable(\$result);
## Setup any keyboard bindings
$self->_set_key_bindings($win);
## Calculate the geometry
$self->_calc_geometry($win);
## Display the window
$win->deiconify;
## Detect user closing the window
$win->protocol('WM_DELETE_WINDOW',sub {$result = 0;});
## See if we are testing
if ($test)
{
## Make sure the string is the correct format
if ($test =~ /TEST:\s+(\d)/x)
{
## 0 == "CANCEL" 1 == "SUBMIT"
$test = $1;
## Set a callback to close the window
$win->after(1500, sub {$result = $test;});
}
}
## See if we have a first field specified
if ($first_field)
{
if ($first_field->is_type($ENTRY))
{
## If this is an entry field, select the entire string
## and place the cursor at the end of the string
$first_field->widget->selectionRange(0, 'end');
$first_field->widget->icursor('end');
}
## Set the focus to the field
$first_field->widget->focus();
}
## Wait for variable to change
$win->waitVariable(\$result);
## Hide the window
$win->withdraw();
## Clear all errors until form data is validated again
$self->clear_errors;
if ($result)
{
lib/Tk/FormUI.pm view on Meta::CPAN
##----------------------------------------------------------------------------
## @fn _set_message($win)
## @brief Set the message at the top of the form's window
## @param $win - Window object
## @return NONE
## @note
##----------------------------------------------------------------------------
sub _set_message
{
my $self = shift;
my $win = shift;
## See if we have a message
if ($self->message)
{
## To keep the message from making the dialog box too
## large, we will look at the current window width and
## wrap the message accordingly
## Allow gemoetry manager to calculate all widgets
$win->update;
## Determine number of rows and columns in the grid
my ($columns, $rows) = $win->gridSize();
## Use the dialog's minimum width as the starting point
my $max_x = $self->min_width;
## Iterate through all rows and columns
my $row = 0;
while ($row < $rows)
{
my $col = 0;
while ($col < $columns)
{
## Get the bounding box of the widget
my ($x, $y, $width, $height) = $win->gridBbox($col, $row);
## Get the max x of the widget
$x += $width;
## See if this is larger than our current max x
$max_x = $x if ($x > $max_x);
## Increment the colums
$col++;
}
## Increment the rows
$row++;
}
## Create a label widget
$win->Label(
-wraplength => $max_x,
-text => $self->message,
-justify => qq{left},
-font => $self->message_font,
)
->grid(
-row => 0,
-rowspan => 1,
-column => 0,
-columnspan => 2,
-sticky => qq{},
);
## Use an empty frame as a spacer
$win->Frame(-height => 5)->grid(-row => 1);
}
return;
}
##****************************************************************************
##****************************************************************************
=head2 initialize($param)
=over 2
=item B<Description>
initialize the form from a HASH reference, JSON string, or JSON file.
In all cases, the hash should have the following format
{
title => 'My Form',
fields => [
{
type => 'Entry',
key => 'name',
label => 'Name',
},
{
type => 'Radiobutton',
key => 'sex',
label => 'Gender',
choices => [
{
label => 'Male',
value => 'male',
},
{
label => 'Female',
value => 'female',
},
],
}
]
}
=item B<Parameters>
$param - HASH reference, or scalar containin JSON string, or filename
=item B<Return>
NONE
=back
( run in 0.566 second using v1.01-cache-2.11-cpan-39bf76dae61 )