File: Alignable.pm

package info (click to toggle)
libtickit-widgets-perl 0.42-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 568 kB
  • sloc: perl: 5,636; makefile: 2
file content (146 lines) | stat: -rw-r--r-- 3,285 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#  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-2023 -- leonerd@leonerd.org.uk

package Tickit::WidgetRole::Alignable 0.52;

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;