App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Gtk2/Ex/WidgetPositionTracker.pm view on Meta::CPAN
}
sub FINALIZE_INSTANCE {
my ($self) = @_;
delete $realized_instances{refaddr($self)};
delete $self->{'alloc_ids'};
}
sub SET_PROPERTY {
my ($self, $pspec, $newval) = @_;
my $pname = $pspec->get_name;
if ($pname eq 'widget') {
FINALIZE_INSTANCE ($self);
delete $self->{'realize_ids'};
App::Chart::Glib::Ex::TieWeakNotify->set ($self, $pname, $newval);
if ($newval) {
if ($newval->flags & 'no-window') {
$self->{'alloc_ids'} = Glib::Ex::SignalIds->new
($newval,
$newval->signal_connect (size_allocate => \&_do_size_allocate,
App::Chart::Glib::Ex::MoreUtils::ref_weak($self)));
}
### realized: $newval->realized
if ($newval->realized) {
_do_realize ($newval, \$self);
} else {
_connect_realize ($self, $newval);
}
}
}
}
# called for size changes as well as position changes, and by the time reach
# here the old size is apparently not available any more: $allocation in
# $parameter->[1] is the same as $widget->allocation.
#
sub _do_size_allocate {
my ($widget, $alloc, $ref_weak_self) = @_;
### size_allocate signal: $widget
my $self = $$ref_weak_self || return;
$self->signal_emit ('moved');
}
sub _connect_realize {
my ($self, $widget) = @_;
### connect realize
$self->{'realize_ids'} = Glib::Ex::SignalIds->new
($widget,
$widget->signal_connect (realize => \&_do_realize,
App::Chart::Glib::Ex::MoreUtils::ref_weak($self)));
### ids: $self->{'realize_ids'}
}
sub _do_realize {
my ($widget, $ref_weak_self) = @_;
### realize signal, window: $widget->window
my $self = $$ref_weak_self || return;
delete $self->{'realize_ids'};
Scalar::Util::weaken ($realized_instances{refaddr($self)} = $self);
$configure_event_hook_id ||= Gtk2::Widget->signal_add_emission_hook
(configure_event => \&_do_configure_event);
}
sub _do_configure_event {
my ($invocation_hint, $parameters) = @_;
my $changed_widget = $parameters->[0];
### configure event: $changed_widget
foreach my $self (values %realized_instances) {
if (my $widget = $self->{'widget'}) {
if ($widget->window) {
if ($changed_widget == $widget
|| $widget->is_ancestor ($changed_widget)) {
$self->signal_emit ('moved');
}
} else {
# was unrealized
FINALIZE_INSTANCE ($self);
_connect_realize ($self, $widget);
}
} else {
# widget weakened away
FINALIZE_INSTANCE ($self);
}
}
if (%realized_instances) {
return 1; # stay connected
} else {
### disconnect hook
undef $configure_event_hook_id;
return 0; # disconnect
}
}
1;
__END__
, values %instances_nowin
$size_allocate_id ||= Gtk2::Widget->signal_add_emission_hook
(size_allocate => \&_do_size_allocate);
sub _do_size_allocate {
my ($invocation_hint, $parameters) = @_;
unless (%instances_nowin) {
undef $size_allocate_id;
return 0; # disconnect
}
my $changed_widget = $parameters->[0];
foreach my $self (values %{$changed_widget->{(__PACKAGE__)}}) {
$self->signal_emit ('moved');
}
return 1; # stay connected
}
if (my $widget = $self->{'widget'}) {
if (my $href = $widget->{(__PACKAGE__)}) {
delete $href->{refaddr($self)};
if (! %$href) {
delete $widget->{(__PACKAGE__)};
}
}
}
my $href = ($newval->{(__PACKAGE__)} ||= {});
$href->{refaddr($self)} = $self;
Scalar::Util::weaken ($href->{refaddr($self)});
my $changed_alloc = $parameters->[1];
my $alloc = $widget->allocation;
print $alloc->width, $changed_alloc->width,"\n";
sub _do_moved {
my ($widget, $allocation, $ref_weak_self) = @_;
my $self = $$ref_weak_self || return;
$self->signal_emit ('moved');
}
} else {
delete $self->{'ids'};
}
use Glib::Ex::SignalIds 5; # version 5 for ->add()
sub _update_connections {
my ($self) = @_;
my $connections = $self->{'connections'};
@$connections = ();
my $widget = $self->{'widget'} || return;
my $ref_weak_self = App::Chart::Glib::Ex::MoreUtils::ref_weak($self);
if ($widget->flags & 'no-window') {
push @$connections,
Glib::Ex::SignalIds->new
($widget,
$widget->signal_connect (size_allocate => \&_do_moved,
$ref_weak_self));
}
do {
my $ids = Glib::Ex::SignalIds->new
($widget,
$widget->signal_connect ('notify::parent', \&_do_reparent,
$ref_weak_self));
if ($widget == $self->{'widget'}
|| ! ($widget->flags & 'no-window')) {
$ids->add ($widget->signal_connect (size_allocate => \&_do_move,
$ref_weak_self));
}
push @$connections, $ids;
} while ($widget = $widget->get_parent);
}
sub _do_reparent {
my $ref_weak_self = $_[-1];
my $self = $$ref_weak_self || return;
_update_connections ($self);
$self->signal_emit ('moved');
}
sub _do_moved {
my $ref_weak_self = $_[-1];
my $self = $$ref_weak_self || return;
$self->signal_emit ('moved');
}
( run in 1.075 second using v1.01-cache-2.11-cpan-39bf76dae61 )