implements build_builtin_object_actions => as {
{
- Update => { base => Update },
- Delete => { base => Delete, attributes => [] },
+ Update => { name => 'Update', base => Update },
+ Delete => { name => 'Delete', base => Delete, attributes => [] },
};
};
implements build_builtin_collection_actions => as {
- { Create => {base => Create } };
+ { Create => {name => 'Create', base => Create } };
};
implements _all_object_actions => as {
for my $action (keys %$actions){
my $action_opts = $self->merge_hashes
($all_actions->{$action} || {}, $actions->{$action} || {});
+
+ #NOTE: If the name of the action is not specified in the prototype then use it's
+ #hash key as the name. I think this is sane beahvior, but I've actually been thinking
+ #of making Action prototypes their own separate objects
$self->reflect_source_action(
name => $action,
object_class => $object,
for my $action (keys %$actions){
my $action_opts = $self->merge_hashes
($all_actions->{$action} || {}, $actions->{$action} || {});
+
+ #NOTE: If the name of the action is not specified in the prototype then use it's
+ #hash key as the name. I think this is sane beahvior, but I've actually been thinking
+ #of making Action prototypes their own separate objects
$self->reflect_source_action(
name => $action,
object_class => $class,
my ($self) = @_;
return join('', map { ucfirst($_) } split('_', $self->name));
};
-
+
};
1;
return $class->new(%{$args||{}}, app => $app);
};
+ sub BUILD{
+ my $self = shift;
+ my $skin_name = $self->skin_name;
+ my $skin_path = $app->path_to('share','skin',$skin_name);
+ confess("'${skin_path}' is not a valid path for skin '${skin_name}'")
+ unless -d $skin_path;
+ }
+
implements 'render_window' => as {
my ($self, $window) = @_;
my $root_vp = $window->focus_stack->vp_head;
has field_names => (isa => 'ArrayRef', is => 'rw', lazy_build => 1);
has _field_map => (
- isa => 'HashRef', is => 'rw', init_arg => 'fields',
- predicate => '_has_field_map', set_or_lazy_build('field_map'),
+ isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1,
);
has exclude_fields =>
( is => 'rw', isa => 'ArrayRef', required => 1, default => sub{ [] } );
- sub fields { shift->_field_map }
+ has ordered_fields => (is => 'rw', isa => 'ArrayRef', lazy_build => 1);
+
+
+ implements fields => as { shift->_field_map };
implements BUILD => as {
my ($self, $args) = @_;
return @fields;
};
- implements build_field_map => as {
+ implements _build_field_map => as {
confess "Lazy field map building not supported by default";
};
+ implements build_ordered_fields => as {
+ my $self = shift;
+ [ map{ $self->_field_map->{$_} } $self->field_names ];
+ };
+
implements build_simple_field => as {
my ($self, $class, $attr, $args) = @_;
my $attr_name = $attr->name;
--- /dev/null
+package Reaction::UI::Widget::DisplayField::Boolean;
+
+use Reaction::UI::WidgetClass;
+
+class Boolean, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value_string } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
+
--- /dev/null
+package Reaction::UI::Widget::DisplayField::Collection;
+
+use Reaction::UI::WidgetClass;
+
+class Collection, which {
+ widget renders [ qw/label list item/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ list renders [ item over func('viewport', 'value_names') ];
+ item renders [ string { $_{_} } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% label %]
+[% list %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout list
+
+<ul>
+[% item %]
+</ul>
+
+=for layout item
+
+<li>[% content %]</li>
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::DateTime;
+
+use Reaction::UI::WidgetClass;
+
+class DateTime, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value_string } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::List;
+
+use Reaction::UI::WidgetClass;
+
+class List, which {
+ widget renders [ qw/label list item/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ list renders [ item over func('viewport', 'value_names') ];
+ item renders [ string { $_{_} } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% label %]
+[% list %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout list
+
+<ul>
+[% item %]
+</ul>
+
+=for layout item
+
+<li>[% content %]</li>
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::Number;
+
+use Reaction::UI::WidgetClass;
+
+class Number, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::RelatedObject;
+
+use Reaction::UI::WidgetClass;
+
+class RelatedObject, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value_string } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::String;
+
+use Reaction::UI::WidgetClass;
+
+class String, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::DisplayField::Text;
+
+use Reaction::UI::WidgetClass;
+
+class Text, which {
+ widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
+ label renders [ string { $_{viewport}->label } ];
+ value renders [ string { $_{viewport}->value } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+[% content %]
+
+=for layout label
+
+<strong > [ % content %]: </strong>
+
+=for layout value
+
+[% content %]
+
+=cut
--- /dev/null
+package Reaction::UI::Widget::ObjectView;
+
+use Reaction::UI::WidgetClass;
+
+class ObjectView, which {
+ widget renders [ fields => { viewport => func('self', 'viewport') } ];
+ field renders [ viewport over func('viewport','ordered_fields') } ];
+};
+
+1;
+
+__END__;
+
+=for layout widget
+
+ [% field %]
+
+=for layout field
+
+ [% content %]<br>
+
+=cut