| Gtk2-Ex-FormFactory documentation | Contained in the Gtk2-Ex-FormFactory distribution. |
Gtk2::Ex::FormFactory::Proxy - Proxy class for application objects
#-- Proxies are always created through
#-- Gtk2::Ex::FormFactory::Context, never
#-- directly by the application.
Gtk2::Ex::FormFactory::Proxy->new (
context => Gtk2::Ex::FormFactory::Context,
object => Object instance or CODEREF,
name => Name of this proxy,
set_prefix => Method prefix for write accessors,
get_prefix => Method prefix for read accessors,
attr_accessors_href => Hashref with accessor callbacks,
attr_activity_href => Hashref with activity callbacks,
aggregated_by => Fully qualified attribute of the parent,
changes_attr_filter => Regex for attributes which should not trigger
the object's 'changed' status
);
This class implements a generic proxy mechanism for accessing application objects and their attributes. It defines attributes of the associated object are accessed. You never instantiate objects of this class by yourself; they're created internally by Gtk2::Ex::FormFactory::Context when adding objects with the Context->add_object() method.
But you may use the proxy objects e.g. for updates which affect the application object and the GUI as well.
You can receive Proxy objects using the Gtk2::Ex::FormFactory::Context->get_proxy() method.
Gtk2::Ex::FormFactory::Proxy
Attributes are handled through the common get_ATTR(), set_ATTR() style accessors.
The Context this proxy belongs to.
The application object itself or a code reference, which returns the object instance.
The Context wide unique name of this Proxy.
This is the method prefix for write accessors. Defaults to set_.
This is the method prefix for read accessors. Defaults to get_.
With this hash you can override specific accessors with a code reference, which is called instead of the object's own accessor.
Refer to Gtk2::Ex::FormFactory::Context->add_object for details.
This hash defines callbacks for attributes which return the activity state of the corresonding attribute.
Refer to Gtk2::Ex::FormFactory::Context->add_object for details.
Fully qualified attribute of the parent aggregating this object
Refer to Gtk2::Ex::FormFactory::Context->add_object for details.
Refer to Gtk2::Ex::FormFactory::Context->add_object for details.
This flag indicates whether the object represented by this Proxy was changed. You may set this attribute to reset the object's changed state.
This returns the actual application object of this Proxy, either the statical assigned instance or a dynamicly retrieved instance.
Changes the application object instance in this Proxy. All dependend Widgets on the GUI are updated accordingly.
Returns the application object's attribute $attr of this Proxy.
If $attr has the form "object.attr" the attribute of the correspondent object is retreived, instead of the object associated with this proxy.
Changes the application object's attribute $attr to $value and updates all dependend Widgets on the GUI accordingly.
If $attr has the form "object.attr" the correspondent object will be updated, instead of the object associated with this proxy.
Changes a bunch of application object's attributes, which is passed as a hash reference with $attr => $value pairs and updates all dependend Widgets on the GUI accordingly.
Returns the current activity state of $attr.
Jörn Reder <joern at zyn dot de>
Copyright 2004-2006 by Jörn Reder.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA.
| Gtk2-Ex-FormFactory documentation | Contained in the Gtk2-Ex-FormFactory distribution. |
package Gtk2::Ex::FormFactory::Proxy; use strict; use Carp; my $NAME_CNT = 0; sub get_context { shift->{context} } sub get_name { shift->{name} } sub get_aggregated_by { shift->{aggregated_by} } sub get_set_prefix { shift->{set_prefix} } sub get_get_prefix { shift->{get_prefix} } sub get_attr_activity_href { shift->{attr_activity_href} } sub get_attr_accessors_href { shift->{attr_accessors_href} } sub get_attr_aggregate_href { shift->{attr_aggregate_href} } sub get_accessor { shift->{accessor} } sub get_changes_attr_filter { shift->{changes_attr_filter} } sub get_buffered { 0 } sub get_object_changed { shift->{object_changed} } sub set_object_changed { shift->{object_changed} = $_[1] } sub new { my $class = shift; my %par = @_; my ($context, $object, $name, $set_prefix, $get_prefix) = @par{'context','object','name','set_prefix','get_prefix'}; my ($attr_accessors_href, $attr_activity_href, $aggregated_by) = @par{'attr_accessors_href','attr_activity_href','aggregated_by'}; my ($accessor, $changes_attr_filter) = @par{'accessor','changes_attr_filter'}; $attr_accessors_href ||= {}, $attr_activity_href ||= {}; $name ||= "object_".$NAME_CNT++; my $self = bless { context => $context, object => $object, name => $name, aggregated_by => $aggregated_by, set_prefix => $set_prefix, get_prefix => $get_prefix, attr_activity_href => $attr_activity_href, attr_accessors_href => $attr_accessors_href, accessor => $accessor, changes_attr_filter => $changes_attr_filter, attr_aggregate_href => {}, }, $class; return $self; } sub get_object { my $self = shift; my $object = $self->{object}; ref $object eq 'CODE' ? &$object() : $object; } sub update_by_aggregation { my $self = shift; my $aggregated_by = $self->get_aggregated_by; my $object = $self->get_attr($aggregated_by); $self->set_object($object); 1; } sub set_object { my $self = shift; my ($object) = @_; #-- nothing to do if it's the same object #-- (eval{} is for catching Class::DBI exceptions if #-- $self->{object} was deleted in the meantime) return if eval { $object eq $self->{object} }; #-- reset changed status $self->set_object_changed(0); #-- set object $self->{object} = $object; #-- Update all object widgets my $context = $self->get_context; $context->update_object_widgets ($self->get_name); #-- Update aggregated objects my $attr_aggregate_href = $self->get_attr_aggregate_href; my ($attr, $child_object_name, $child_object); while ( ($attr, $child_object_name) = each %{$attr_aggregate_href} ) { $child_object = $self->get_attr($attr); $context->set_object($child_object_name, $child_object); } return $object; } sub get_attr { my $self = shift; my ($attr_name) = @_; if ( $attr_name =~ /^([^.]+)\.(.*)$/ ) { $self = $self->get_context->get_proxy($1); $attr_name = $2; } my $accessor = $self->get_accessor; my $object = $self->get_object; return &$accessor($object, $attr_name) if $accessor; my $method = $self->get_get_prefix.$attr_name; $accessor = $self->get_attr_accessors_href->{$method}; return if not $object; return &$accessor($object) if $accessor; return $object->$method(); } sub set_attr { my $self = shift; my ($attr_name, $attr_value, $no_widget_update) = @_; if ( $attr_name =~ /^([^.]+)\.(.*)$/ ) { $self = $self->get_context->get_proxy($1); $attr_name = $2; } $self->object_changed($attr_name); my $accessor = $self->get_accessor; my $object = $self->get_object; my $name = $self->get_name; my $rc; if ( $accessor ) { $rc = &$accessor($object, $attr_name, $attr_value); } else { my $set_prefix = $self->get_set_prefix; my $method = $set_prefix.$attr_name; $accessor = $self->get_attr_accessors_href->{$method}; $rc = $accessor ? &$accessor($object, $attr_value) : $object->$method($attr_value); } return $rc if $no_widget_update; $self->get_context ->update_object_attr_widgets($name, $attr_name, $object); my $child_object_name = $self->get_attr_aggregate_href->{$attr_name}; $self->get_context->set_object($child_object_name, $attr_value) if $child_object_name; return $rc; } sub set_attrs { my $self = shift; my ($attrs_href, $no_widget_update) = @_; my $set_prefix = $self->get_set_prefix; my $object = $self->get_object; my $name = $self->get_name; my $context = $self->get_context; my $accessors = $self->get_attr_accessors_href; my ($method, $attr_name, $attr_value, $accessor, $child_object_name); $accessor = $self->get_accessor; while ( ($attr_name, $attr_value) = each %{$attrs_href} ) { $self->object_changed($attr_name); if ( $accessor ) { &$accessor($object, $attr_name, $attr_value); } else { $method = $set_prefix.$attr_name; $accessor = $accessors->{$method}; $accessor ? &$accessor($object, $attr_value) : $object->$method($attr_value); } $accessor = undef; next if $no_widget_update; $context->update_object_attr_widgets( $name, $attr_name, $object ); $child_object_name = $self->get_attr_aggregate_href->{$attr_name}; $context->set_object($child_object_name, $attr_value) if $child_object_name; } 1; } sub get_attr_presets { my $self = shift; my ($attr_name) = @_; my $method = $self->get_get_prefix.$attr_name."_presets"; my $object = $self->get_object; my $accessor = $self->get_attr_accessors_href->{$method}; return &$accessor($object) if ref $accessor eq 'CODE'; return $accessor if $accessor; return $object->$method(); } sub get_attr_rows { my $self = shift; my ($attr_name) = @_; my $method = $self->get_get_prefix.$attr_name."_rows"; my $object = $self->get_object; my $accessor = $self->get_attr_accessors_href->{$method}; return &$accessor($object) if ref $accessor eq 'CODE'; return $accessor if $accessor; return $object->$method(); } sub get_attr_list { my $self = shift; my ($attr_name, $widget_name) = @_; my $method = $self->get_get_prefix.$attr_name."_list"; my $object = $self->get_object; my $accessor = $self->get_attr_accessors_href->{$method}; return &$accessor($object, $widget_name) if ref $accessor eq 'CODE'; return $accessor if $accessor; return $object->$method($widget_name); } sub get_attr_presets_static { my $self = shift; my ($attr_name) = @_; my $method = $self->get_get_prefix.$attr_name."_presets_static"; my $object = $self->get_object; my $accessor = $self->get_attr_accessors_href->{$method}; return &$accessor($object) if ref $accessor eq 'CODE'; return $accessor if $accessor; return 1 if not $object->can($method); return $object->$method(); } sub get_attr_rows_static { my $self = shift; my ($attr_name) = @_; my $method = $self->get_get_prefix.$attr_name."_rows_static"; my $object = $self->get_object; my $accessor = $self->get_attr_accessors_href->{$method}; return &$accessor($object) if ref $accessor eq 'CODE'; return $accessor if $accessor; return 1 if not $object->can($method); return $object->$method(); } sub get_attr_list_static { my $self = shift; my ($attr_name) = @_; my $method = $self->get_get_prefix.$attr_name."_list_static"; my $object = $self->get_object; return 1 if not $object->can($method); return $object->$method(); } sub get_attr_activity { my $self = shift; my ($attr_name) = @_; $Gtk2::Ex::FormFactory::DEBUG && print " proxy->get_attr_activity($attr_name)\n"; my $object = $self->get_object; return 0 if not defined $object; my $attr_activity_href = $self->get_attr_activity_href; return 1 if not $attr_activity_href or not exists $attr_activity_href->{$attr_name}; my $attr_activity = $attr_activity_href->{$attr_name}; return $attr_activity if not ref $attr_activity eq 'CODE'; return &$attr_activity($object); } sub object_changed { my $self = shift; my ($attr_name) = @_; my $changes_attr_filter = $self->get_changes_attr_filter; if ( !$changes_attr_filter || $attr_name !~ $changes_attr_filter ) { $self->set_object_changed(1); my $aggregated_by = $self->get_aggregated_by; if ( $aggregated_by ) { my $context = $self->get_context; my ($object, $attr) = $context->norm_object_attr($aggregated_by); $context->get_proxy($object)->object_changed($attr); } } 1; } 1; __END__