Gtk2-Ex-Xor
view release on metacpan or search on metacpan
t/CrossHair.t view on Meta::CPAN
#-----------------------------------------------------------------------------
require Gtk2;
MyTestHelpers::glib_gtk_versions();
# setting 'widget' notifies 'widgets' too
{
my $widget = Gtk2::Window->new ('toplevel');
my $cross = Gtk2::Ex::CrossHair->new;
my $seen_widget = 0;
my $seen_widgets = 0;
$cross->signal_connect ('notify::widget' => sub { $seen_widget++; });
$cross->signal_connect ('notify::widgets' => sub { $seen_widgets++; });
$cross->set (widget => $widget);
is ($seen_widget, 1, 'notify widget');
is ($seen_widgets, 1, 'notify widgets');
$widget->destroy;
}
# setting 'widgets' notifies 'widget' too
{
my $widget = Gtk2::Window->new ('toplevel');
my $cross = Gtk2::Ex::CrossHair->new;
my $seen_widget = 0;
my $seen_widgets = 0;
$cross->signal_connect ('notify::widget' => sub { $seen_widget++; });
$cross->signal_connect ('notify::widgets' => sub { $seen_widgets++; });
$cross->set (widgets => [$widget]);
is ($seen_widget, 1, 'notify widget');
is ($seen_widgets, 1, 'notify widgets');
$widget->destroy;
}
# destroyed when weakened empty
{
my $cross = Gtk2::Ex::CrossHair->new;
my $weak_cross = $cross;
require Scalar::Util;
Scalar::Util::weaken ($weak_cross);
undef $cross;
is ($weak_cross, undef, 'weaken empty - destroyed');
if (defined &explain) { diag explain($weak_cross); }
if ($weak_cross) { MyTestHelpers::findrefs ($weak_cross); }
}
# destroyed when weakened on unrealized
{
my $widget = Gtk2::Window->new ('toplevel');
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
my $weak_cross = $cross;
require Scalar::Util;
Scalar::Util::weaken ($weak_cross);
undef $cross;
MyTestHelpers::main_iterations();
is ($weak_cross, undef, 'weaken unrealized - destroyed');
if (defined &explain) {
diag explain($widget);
diag explain($weak_cross);
}
if ($weak_cross) {
MyTestHelpers::findrefs ($weak_cross);
}
is_deeply (leftover_fields($widget), [],
'weaken unrealized - no CrossHair data left behind');
$widget->destroy;
}
# destroyed when weakened on realized
{
my $widget = Gtk2::Window->new ('toplevel');
$widget->realize;
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
my $weak_cross = $cross;
Scalar::Util::weaken ($weak_cross);
$cross = undef;
is ($weak_cross, undef, 'weaken realized - destroyed');
is_deeply (leftover_fields($widget), [],
'weaken realized - no CrossHair data left behind');
$widget->destroy;
}
# destroyed when weakened on active
SKIP: {
Gtk2::Gdk::Display->can('warp_pointer')
or skip 'no display->warp_pointer(), per Gtk before 2.8', 3;
my $widget = Gtk2::Window->new ('toplevel');
$widget->set_size_request (100, 100);
show_wait ($widget);
# temporary warp to have mouse pointer within $widget
my $display = $widget->get_display;
my ($screen,$x,$y) = $display->get_pointer;
my ($widget_x,$widget_y) = $widget->window->get_origin;
$display->warp_pointer($widget->get_screen,$widget_x+50,$widget_y+50);
is_deeply (leftover_fields($widget), [],
'weaken active - initially no CrossHair data');
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
$cross->start;
# sync and iterate to make the cross draw and use its gc
$display->sync;
MyTestHelpers::main_iterations();
my $weak_cross = $cross;
Scalar::Util::weaken ($weak_cross);
$cross = undef;
MyTestHelpers::main_iterations();
is ($weak_cross, undef, 'weaken active - destroyed');
if ($weak_cross) {
if (defined &explain) { diag explain($weak_cross); }
MyTestHelpers::findrefs ($weak_cross);
}
is_deeply (leftover_fields($widget), [],
'weaken active - no CrossHair data left behind');
$widget->destroy;
$display->warp_pointer($screen,$x,$y);
}
# start() emits "notify::active"
{
my $widget = Gtk2::Window->new ('toplevel');
$widget->realize;
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
my $seen_notify = 0;
$cross->signal_connect ('notify::active' => sub { $seen_notify = 1; });
$cross->start;
is ($seen_notify, 1, 'start() emits notify::active');
$widget->destroy;
}
# end() emits "notify::active"
{
my $widget = Gtk2::Window->new ('toplevel');
$widget->realize;
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
$cross->start;
my $seen_notify = 0;
$cross->signal_connect ('notify::active' => sub { $seen_notify = 1; });
$cross->end;
is ($seen_notify, 1, 'end() emits notify::active');
$widget->destroy;
}
# leftovers on changing widget, and switching to a widget without a common
# ancestor with the previous
SKIP: {
Gtk2::Gdk::Display->can('warp_pointer')
or skip 'no display->warp_pointer(), per Gtk before 2.8', 2;
my $widget = Gtk2::Window->new ('toplevel');
my $widget2 = Gtk2::Window->new ('toplevel');
$widget->set_size_request (100, 100);
show_wait ($widget);
show_wait ($widget2);
# temporary warp to have mouse pointer within $widget
my $display = $widget->get_display;
my ($screen,$x,$y) = $display->get_pointer;
my ($widget_x,$widget_y) = $widget->window->get_origin;
$display->warp_pointer($widget->get_screen,$widget_x+50,$widget_y+50);
my $cross = Gtk2::Ex::CrossHair->new (widget => $widget);
$cross->start;
# sync and iterate to make the cross draw and use its gc
$display->sync;
MyTestHelpers::main_iterations();
$cross->set (widget => $widget2);
($widget_x,$widget_y) = $widget2->window->get_origin;
$display->warp_pointer($widget2->get_screen,$widget_x+50,$widget_y+50);
$display->sync;
MyTestHelpers::main_iterations();
# if (defined &explain) {
# diag explain($widget);
# }
is_deeply (leftover_fields($widget), [],
'change widget - no CrossHair data left behind');
$cross->set (widgets => []);
is_deeply (leftover_fields($widget2), [],
'change to no widgets - no CrossHair data left behind');
$widget->destroy;
$widget2->destroy;
$display->warp_pointer($screen,$x,$y);
}
#------------------------------------------------------------------------------
# foreground properties
# return true if two Glib::Boxed objects $b1 and $b2 point to the same
# underlying C object
{
my $n = 0;
sub color_parts {
my ($color) = @_;
if (Scalar::Util::blessed($color)) {
return $color->red .','. $color->blue .','. $color->green;
} else {
return 'not-a-color-object'.$n++;
}
}
}
{
my $crosshair = Gtk2::Ex::CrossHair->new;
my %notifies;
$crosshair->signal_connect (notify => sub {
my ($crosshair, $pspec) = @_;
my $pname = $pspec->get_name;
$notifies{$pname} = 1;
});
# claimed defaults
is ($crosshair->get('foreground'), undef, 'foreground - default undef');
is ($crosshair->get('foreground-name'), undef, 'foreground-name - default undef');
is ($crosshair->get('foreground-gdk'), undef,
'foreground-gdk - default undef');
# string
%notifies = ();
$crosshair->set (foreground => 'white');
is ($crosshair->get('foreground'), 'white');
is ($crosshair->get('foreground-name'), 'white');
is (color_parts ($crosshair->get('foreground-gdk')),
color_parts (Gtk2::Gdk::Color->new(65535,65535,65535)));
is_deeply (\%notifies, {foreground=>1,foreground_name=>1,foreground_gdk=>1},
'foreground string notifies');
# object
my $red = Gtk2::Gdk::Color->new (65535,0,0);
( run in 2.248 seconds using v1.01-cache-2.11-cpan-751830e7986 )