aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Reaction/UI/LayoutSet.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Reaction/UI/LayoutSet.pm')
-rw-r--r--lib/Reaction/UI/LayoutSet.pm52
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Reaction/UI/LayoutSet.pm b/lib/Reaction/UI/LayoutSet.pm
new file mode 100644
index 0000000..793568f
--- /dev/null
+++ b/lib/Reaction/UI/LayoutSet.pm
@@ -0,0 +1,52 @@
+package Reaction::UI::LayoutSet;
+
+use Reaction::Class;
+use File::Spec;
+
+class LayoutSet which {
+
+ has 'fragments' => (is => 'ro', default => sub { {} });
+
+ has 'name' => (is => 'ro', required => 1);
+
+ has 'source_file' => (is => 'rw', lazy_fail => 1);
+
+ implements 'BUILD' => as {
+ my ($self, $args) = @_;
+ my @path = @{$args->{search_path}||[]};
+ confess "No search_path provided" unless @path;
+ my $found;
+ SEARCH: foreach my $path (@path) {
+ my $cand = $path->file($self->name);
+ if ($cand->stat) {
+ $self->_load_file($cand);
+ $found = 1;
+ last SEARCH;
+ }
+ }
+ confess "Unable to load file for LayoutSet ".$self->name unless $found;
+ };
+
+ implements '_load_file' => as {
+ my ($self, $file) = @_;
+ my $data = $file->slurp;
+ my $fragments = $self->fragments;
+ # cheesy match for "=for layout fragmentname ... =something"
+ # final split group also handles last in file, (?==) is lookahead
+ # assertion for '=' so "=for layout fragment1 ... =for layout fragment2"
+ # doesn't have the match pos go past the latter = and lose fragment2
+ while ($data =~ m/=for layout (.*?)\n(.+?)(?:\n(?==)|$)/sg) {
+ my ($fname, $text) = ($1, $2);
+ $fragments->{$fname} = $text;
+ }
+ $self->source_file($file);
+ };
+
+ implements 'widget_type' => as {
+ my ($self) = @_;
+ return join('', map { ucfirst($_) } split('_', $self->name));
+ };
+
+};
+
+1;