# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
# (C) Paul Evans, 2012-2020 -- leonerd@leonerd.org.uk
package Tickit::WidgetRole::Alignable 0.51;
use v5.14;
use warnings;
use base qw( Tickit::WidgetRole );
use Carp;
use Tickit::Utils qw( align );
=head1 NAME
C<Tickit::WidgetRole::Alignable> - implement widgets with adjustable alignment
=head1 DESCRIPTION
Mixing this parametric role into a L<Tickit::Widget> subclass adds behaviour
to implement alignment of content within a possibly-larger space.
=cut
=head1 METHODS
The following methods are provided parametrically on the caller package when
the module is imported by
use Tickit::WidgetRole::Alignable
name => NAME,
style => STYLE,
reshape => RESHAPE;
The parameters are
=over 4
=item name => STRING
Optional. The name to use for C<NAME> in the following generated methods.
Defaults to C<'align'> if not provided.
=item dir => "h" or "v"
Optional. The direction, horizontal or vertical, that the alignment
represents. Used to parse symbolic names into fractions. Defaults to C<'h'> if
not provided.
=item reshape => BOOL
Optional. If true, the widget will be reshaped after the value has been set by
calling the C<reshape> method. If false or absent then it will just be redrawn
by calling C<redraw>.
=back
=cut
my %symbolics = (
h => { left => 0.0, centre => 0.5, right => 1.0 },
v => { top => 0.0, middle => 0.5, bottom => 1.0 },
);
sub export_subs_for
{
my $class = shift;
shift;
my %args = @_;
my $name = $args{name} || "align";
my $dir = $args{dir} || "h";
my $post_set_method = $args{reshape} ? "reshape" : "redraw";
my $symbolics = $symbolics{$dir} or croak "Unrecognised dir - $dir";
return {
"$name" => sub {
my $self = shift;
return $self->{$name};
},
"set_$name" => sub {
my $self = shift;
my ( $align ) = @_;
# Convert symbolics
$align = $symbolics->{$align} if exists $symbolics->{$align};
$self->{$name} = $align;
$self->$post_set_method;
},
"_${name}_allocation" => sub {
my $self = shift;
my ( $value, $total ) = @_;
return align( $value, $total, $self->$name );
},
};
}
=head2 I<NAME>
$align = $widget->NAME
Return the current alignment value
=cut
=head2 set_I<NAME>
$widget->set_NAME( $value )
Set the new alignment value
Gives a value in the range from C<0.0> to C<1.0> to align the content display
within the window.
For vertical direction alignments, the symbolic values C<top>, C<middle> and
C<bottom> can be supplied instead of C<0.0>, C<0.5> and C<1.0> respectively.
For horizontal direction alignments, the symbolic values C<left>, C<centre>
and C<right> can be supplied instead of C<0.0>, C<0.5> and C<1.0>
respectively.
=head2 _I<NAME>_allocation
( $before, $alloc, $after ) = $widget->_NAME_allocation( $value, $total )
Returns a list of three integers created by aligning the C<$value> to the
given alignment position within the C<$total>. See also C<align> in
L<Tickit::Utils>.
=cut
=head1 AUTHOR
Paul Evans <leonerd@leonerd.org.uk>
=cut
0x55AA;