16 |
my $halign = shift; |
my $halign = shift; |
17 |
|
|
18 |
$self->attribute("lam:halign", $halign) if defined ($halign); |
$self->attribute("lam:halign", $halign) if defined ($halign); |
19 |
return $self->attribute("halign") || "left"; |
return $self->attribute("lam:halign") || "left"; |
20 |
} |
} |
21 |
|
|
22 |
sub valign |
sub valign |
25 |
my $valign = shift; |
my $valign = shift; |
26 |
|
|
27 |
$self->attribute("lam:valign", $valign) if defined ($valign); |
$self->attribute("lam:valign", $valign) if defined ($valign); |
28 |
return $self->attribute("valign") || "top"; |
return $self->attribute("lam:valign") || "top"; |
29 |
|
} |
30 |
|
|
31 |
|
sub boxtype |
32 |
|
{ |
33 |
|
my $self = shift; |
34 |
|
my $boxtype = shift; |
35 |
|
|
36 |
|
$self->attribute("lam:boxtype", $boxtype) if defined ($boxtype); |
37 |
|
return $self->attribute("lam:boxtype") || "v"; |
38 |
} |
} |
39 |
|
|
40 |
sub contents_width |
sub contents_width |
65 |
return $self->y; |
return $self->y; |
66 |
} |
} |
67 |
|
|
68 |
|
sub align_vertically |
69 |
|
{ |
70 |
|
my $self = shift; |
71 |
|
my @alignees = @_; |
72 |
|
my $alignment = $self->halign; |
73 |
|
|
74 |
|
foreach my $object (@alignees) |
75 |
|
{ |
76 |
|
# If object's width not set, make it as wide as the box |
77 |
|
my $width = $object->width || $object->width($self->contents_width); |
78 |
|
|
79 |
|
# Place object in the vertical according to alignment |
80 |
|
$object->x($self->contents_origin_x + $self->contents_width - $object->width), next if $alignment =~ /^r/i; # |
81 |
|
$object->x(int(($self->contents_origin_x + $self->contents_width - $object->width)/2)), next if $alignment =~ /^c/i; |
82 |
|
$object->x($self->contents_origin_x); # Default case: left alignment |
83 |
|
} |
84 |
|
} |
85 |
|
|
86 |
|
sub layout_vertically |
87 |
|
{ |
88 |
|
my $self = shift; |
89 |
|
my @alignees = @_; |
90 |
|
my $free_space = $self->contents_height; |
91 |
|
my @stretchable = (); |
92 |
|
|
93 |
|
foreach my $object (@alignees) |
94 |
|
{ |
95 |
|
my $height = $object->height; |
96 |
|
# If height is defined, then that space is taken. |
97 |
|
# If height undefined, record object to be stretched |
98 |
|
defined($height) ? $free_space -= $height : push(@stretchable, $object); |
99 |
|
} |
100 |
|
$free_space < 0 and $free_space = 0; # make sure free space not negative |
101 |
|
|
102 |
|
# Distribute free space among stretchable items, if any |
103 |
|
if (0 < @stretchable) |
104 |
|
{ |
105 |
|
my $stretch = $free_space/@stretchable; # Spread free space equanimously |
106 |
|
map {$free_space -= $_->height(int($stretch)||1)} @stretchable; # Set height of flexible items |
107 |
|
} |
108 |
|
|
109 |
|
# Now lay out the elements |
110 |
|
my $alignment = $self->valign; |
111 |
|
my $cursor = $self->contents_origin_y; # Default alignment is top |
112 |
|
$cursor += int($free_space/2) if $alignment =~ /^c/i; |
113 |
|
$cursor += $free_space if $alignment =~ /^b/i; |
114 |
|
map {$_->y($cursor); $cursor += $_->height} @alignees; |
115 |
|
|
116 |
|
} |
117 |
|
|
118 |
|
sub align_horizontally |
119 |
|
{ |
120 |
|
my $self = shift; |
121 |
|
my @alignees = @_; |
122 |
|
my $alignment = $self->valign; |
123 |
|
|
124 |
|
foreach my $object (@alignees) |
125 |
|
{ |
126 |
|
# If object's height not set, make it as high as the box |
127 |
|
my $height = $object->height || $object->height($self->contents_height); |
128 |
|
|
129 |
|
# Place object in the vertical according to alignment |
130 |
|
$object->y($self->contents_origin_y + $self->contents_height - $object->height), next if $alignment =~ /^b/i; |
131 |
|
$object->y(int(($self->contents_origin_y + $self->contents_height - $object->height)/2)), next if $alignment =~ /^c/i; |
132 |
|
$object->y($self->contents_origin_y); # Default case: top alignment |
133 |
|
} |
134 |
|
} |
135 |
|
|
136 |
|
sub layout_horizontally |
137 |
|
{ |
138 |
|
my $self = shift; |
139 |
|
my @alignees = @_; |
140 |
|
my $free_space = $self->contents_width; |
141 |
|
my @stretchable = (); |
142 |
|
|
143 |
|
foreach my $object (@alignees) |
144 |
|
{ |
145 |
|
my $width = $object->width; |
146 |
|
# If width is defined, then that space is taken. |
147 |
|
# If width undefined, record object to be stretched |
148 |
|
defined($width) ? $free_space -= $width : push(@stretchable, $object); |
149 |
|
} |
150 |
|
$free_space < 0 and $free_space = 0; # make sure free space not negative |
151 |
|
|
152 |
|
# Distribute free space among stretchable items, if any |
153 |
|
if (0 < @stretchable) |
154 |
|
{ |
155 |
|
my $stretch = $free_space/@stretchable; # Spread free space equanimously |
156 |
|
map {$free_space -= $_->width(int($stretch)||1)} @stretchable; # Set width of flexible items |
157 |
|
} |
158 |
|
|
159 |
|
# Now lay out the elements |
160 |
|
my $alignment = $self->halign; |
161 |
|
my $cursor = $self->contents_origin_x; # Default alignment is left |
162 |
|
$cursor += int($free_space/2) if $alignment =~ /^c/i; # Advance cursor by free/2: centered |
163 |
|
$cursor += $free_space if $alignment =~ /^r/i; # Advance cursor by free: flush right |
164 |
|
map {$_->x($cursor); $cursor += $_->width} @alignees; |
165 |
|
|
166 |
|
} |
167 |
|
|
168 |
|
sub align |
169 |
|
{ |
170 |
|
my $self = shift; |
171 |
|
|
172 |
|
$self->boxtype =~ /^h/i ? $self->align_horizontally(@_) : $self->align_vertically(@_); |
173 |
|
} |
174 |
|
|
175 |
|
sub layout |
176 |
|
{ |
177 |
|
my $self = shift; |
178 |
|
|
179 |
|
$self->boxtype =~ /^h/i ? $self->layout_horizontally(@_) : $self->layout_vertically(@_); |
180 |
|
} |
181 |
|
|
182 |
1; |
1; |