summaryrefslogtreecommitdiffstats
path: root/perl-install/standalone/icons/wiz_default_left.png
blob: 2300ab36ee146afec31f6c4cb934ee64e075c148 (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 64 00 00 01 2c 08 02 00 00 00 ba fc 81 .PNG........IHDR...d...,........
0020 b6 00 00 00 04 67 41 4d 41 00 00 d6 d8 d4 4f 58 32 00 00 00 19 74 45 58 74 53 6f 66 74 77 61 72 .....gAMA.....OX2....tEXtSoftwar
0040 65 00 41 64 6f 62 65 20 49 6d 61 67 65 52 65 61 64 79 71 c9 65 3c 00 00 08 1b 49 44 41 54 78 da e.Adobe.ImageReadyq.e<....IDATx.
0060 62 54 74 99 c3 30 0a 88 03 00 01 c4 34 1a 04 c4 03 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 bTt..0......4........,..@.......
0080 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 .F.....@..E......"....h`....h4.H
00a0 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 ...4.X$.....,..@........F.....@.
00c0 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 .E......"....h`....h4.H...4.X$..
00e0 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 ...,..@........F.....@..E......"
0100 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d ....h`....h4.H...4.X$.....,..@..
0120 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 ......F.....@..E......"....h`...
0140 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b .h4.H...4.X$.....,..@........F..
0160 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 ...@..E......"....h`....h4.H...4
0180 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 .X$.....,..@........F.....@..E..
01a0 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c ...."....h`....h4.H...4.X$.....,
01c0 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 ..@........F.....@..E......"....
01e0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 h`....h4.H...4.X$.....,..@......
0200 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 ..F.....@..E......"....h`....h4.
0220 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 H...4.X$.....,..@........F.....@
0240 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 ..E......"....h`....h4.H...4.X$.
0260 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 ....,..@........F.....@..E......
0280 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 "....h`....h4.H...4.X$.....,..@.
02a0 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 .......F.....@..E......"....h`..
02c0 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 ..h4.H...4.X$.....,..@........F.
02e0 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 ....@..E......"....h`....h4.H...
0300 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 4.X$.....,..@........F.....@..E.
0320 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d ....."....h`....h4.H...4.X$.....
0340 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 ,..@........F.....@..E......"...
0360 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 .h`....h4.H...4.X$.....,..@.....
0380 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 ...F.....@..E......"....h`....h4
03a0 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 .H...4.X$.....,..@........F.....
03c0 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 @..E......"....h`....h4.H...4.X$
03e0 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 .....,..@........F.....@..E.....
0400 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 ."....h`....h4.H...4.X$.....,..@
0420 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 ........F.....@..E......"....h`.
0440 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 ...h4.H...4.X$.....,..@........F
0460 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 .....@..E......"....h`....h4.H..
0480 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 .4.X$.....,..@........F.....@..E
04a0 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a ......"....h`....h4.H...4.X$....
04c0 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 .,..@........F.....@..E......"..
04e0 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 ..h`....h4.H...4.X$.....,..@....
0500 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 ....F.....@..E......"....h`....h
0520 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 4.H...4.X$.....,..@........F....
0540 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 .@..E......"....h`....h4.H...4.X
0560 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 $.....,..@........F.....@..E....
0580 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 .."....h`....h4.H...4.X$.....,..
05a0 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 @........F.....@..E......"....h`
05c0 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 ....h4.H...4.X$.....,..@........
05e0 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 F.....@..E......"....h`....h4.H.
0600 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 ..4.X$.....,..@........F.....@..
0620 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 E......"....h`....h4.H...4.X$...
0640 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 ..,..@........F.....@..E......".
0660 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 ...h`....h4.H...4.X$.....,..@...
0680 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 .....F.....@..E......"....h`....
06a0 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 h4.H...4.X$.....,..@........F...
06c0 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a ..@..E......"....h`....h4.H...4.
06e0 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 X$.....,..@........F.....@..E...
0700 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 ..."....h`....h4.H...4.X$.....,.
0720 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 .@........F.....@..E......"....h
0740 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 `....h4.H...4.X$.....,..@.......
0760 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 .F.....@..E......"....h`....h4.H
0780 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 ...4.X$.....,..@........F.....@.
07a0 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 .E......"....h`....h4.H...4.X$..
07c0 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 ...,..@........F.....@..E......"
07e0 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d ....h`....h4.H...4.X$.....,..@..
0800 06 16 09 00 20 80 46 03 8b 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 ......F.....@..E......"....h`...
0820 02 68 34 b0 48 00 00 01 34 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 80 46 03 8b .h4.H...4.X$.....,..@........F..
0840 04 00 10 40 a3 81 45 02 00 08 a0 d1 c0 22 01 00 04 d0 68 60 91 00 00 02 68 34 b0 48 00 00 01 34 ...@..E......"....h`....h4.H...4
0860 1a 58 24 00 80 00 1a 0d 2c 12 00 40 00 8d 06 16 09 00 20 c0 00 04 5a 03 59 0b ce 0f 4b 00 00 00 .X$.....,..@..........Z.Y...K...
0880 00 49 45 4e 44 ae 42 60 82 .IEND.B`.
n461' href='#n461'>461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
package mygtk2;

use diagnostics;
use strict;
use lang;

our @ISA = qw(Exporter);
our @EXPORT = qw(gtknew gtkset gtkadd gtkval_register gtkval_modify);

use c;
use log;
use common;

use Gtk2;
use Gtk2::Gdk::Keysyms;

unless ($::no_ugtk_init) {
    !check_for_xserver() and print("Cannot be run in console mode.\n"), c::_exit(0);
    $::one_message_has_been_translated and warn("N() was called from $::one_message_has_been_translated BEFORE gtk2 initialisation, replace it with a N_() AND a translate() later.\n"), c::_exit(1);

    Gtk2->init;
    c::bind_textdomain_codeset($_, 'UTF8') foreach 'libDrakX', @::textdomains;
    $::need_utf8_i18n = 1;
}
Gtk2->croak_execeptions if (!$::no_ugtk_init || $::isInstall) && 0.95 < $Gtk2::VERSION;



sub gtknew {
    my $class = shift;
    if (@_ % 2 != 0) {
	internal_error("gtknew $class: bad options @_");
    }
    if (my $r = find { ref $_->[0] } group_by2(@_)) {
	internal_error("gtknew $class: $r should be a string in @_");
    }
    _gtk(undef, $class, 'gtknew', @_);
}

sub gtkset {
    my $w = shift;
    my $class = ref($w);
    if (@_ % 2 != 0) {
	internal_error("gtkset $class: bad options @_");
    }
    if (my $r = find { ref $_->[0] } group_by2(@_)) {
	internal_error("gtkset $class: $r should be a string in @_");
    }
    $class =~ s/^Gtk2::(Gdk::)?// or internal_error("gtkset unknown class $class");
    
    _gtk($w, $class, 'gtkset', @_);
}

sub gtkadd {
    my $w = shift;
    my $class = ref($w);
    if (@_ % 2 != 0) {
	internal_error("gtkadd $class: bad options @_");
    }
    if (my $r = find { ref $_->[0] } group_by2(@_)) {
	internal_error("gtkadd $class: $r should be a string in @_");
    }
    $class =~ s/^Gtk2::(Gdk::)?// or internal_error("gtkadd unknown class $class");
    
    _gtk('gtkadd', $w, $class, @_);
}


my %refs;

sub gtkval_register {
    my ($w, $ref, $sub) = @_;
    $w->{_ref} = $ref;
    $w->signal_connect(destroy => sub { 
	delete $refs{$ref}{$w};
	delete $refs{$ref} if !%{$refs{$ref}};
    });
    push @{$refs{$ref}{$w}}, [ $sub, $w ];
}
sub gtkval_modify {
    my ($ref, $val, @to_skip) = @_;
    $$ref = $val;
    foreach (map { @$_ } values %{$refs{$ref} || {}}) {	
	my ($f, @para) = @$_;
	$f->(@para) if !member($f, @to_skip);
    }
}

my $global_tooltips;

sub _gtk {
    my ($w, $class, $action, %opts) = @_;

    my @known_opts = ('width', 'height', 'position', 'can_focus', 'widget_name', 'grab_focus', 'tip', 'size_group');

    if (my $f = $mygtk2::{"_gtk__$class"}) {
	$w = $f->($w, \%opts, $class, $action);
    } else {
	internal_error("$action $class: unknown class");
    }

    $w->set_size_request($opts{width} || -1, $opts{height} || -1) if $opts{width} || $opts{height};
    $w->set_uposition($opts{position}[0], $opts{position}[1]) if $opts{position};
    $w->set_name($opts{widget_name}) if $opts{widget_name};
    $w->can_focus($opts{can_focus}) if defined $opts{can_focus};
    $w->grab_focus if $opts{grab_focus};
    $opts{size_group}->add_widget($w) if $opts{size_group};
    if ($opts{tip}) {
	$global_tooltips ||= Gtk2::Tooltips->new;
	$global_tooltips->set_tip($w, $opts{tip});
    }

    delete $opts{$_} foreach @known_opts;
    if (%opts && !$opts{allow_unknown_options}) {
	internal_error("$action $class: unknown option(s) " . join(', ', keys %opts));
    }
    $w;
}


sub _gtk__Button       { &_gtk_any_Button }
sub _gtk__ToggleButton { &_gtk_any_Button }
sub _gtk__CheckButton  { &_gtk_any_Button }
sub _gtk_any_Button {
    my ($w, $opts, $class) = @_;

    if (!$opts->{image}) {
	add2hash_($opts, { mnemonic => 1 });
    }

    if (!$w) {
	$w = $opts->{image} ? "Gtk2::$class"->new :
	  delete $opts->{mnemonic} ? "Gtk2::$class"->new_with_mnemonic(delete $opts->{text} || '') :
	    "Gtk2::$class"->new_with_label(delete $opts->{text} || '');

	$w->{format} = delete $opts->{format} if exists $opts->{format};
    }

    if (my $image = delete $opts->{image}) {
	$w->add($image);
	$image->show;
    }
    $w->set_sensitive(delete $opts->{sensitive}) if exists $opts->{sensitive};
    $w->set_relief(delete $opts->{relief}) if exists $opts->{relief};

    if (my $text_ref = delete $opts->{text_ref}) {
	my $set = sub {
	    eval { $w->set_label(may_apply($w->{format}, $$text_ref)) };
	};
	gtkval_register($w, $text_ref, $set);
	$set->();
    }

    if ($class eq 'Button') {
	$w->signal_connect(clicked => delete $opts->{clicked}) if exists $opts->{clicked};
    } else {
	if (my $active_ref = delete $opts->{active_ref}) {
	    my $set = sub { $w->set_active($$active_ref) };
	    $w->signal_connect(toggled => sub {
		gtkval_modify($active_ref, $w->get_active, $set);
	    });
	    gtkval_register($w, $active_ref, $set);
	    gtkval_register($w, $active_ref, delete $opts->{toggled}) if exists $opts->{toggled};
	    $set->();
	} else {
	    $w->set_active(delete $opts->{active}) if exists $opts->{active};
	    $w->signal_connect(toggled => delete $opts->{toggled}) if exists $opts->{toggled};
	}
    }
    $w;
}

sub _gtk__CheckMenuItem {
    my ($w, $opts, $class) = @_;

    if (!$w) {
	add2hash_($opts, { mnemonic => 1 });

	$w = $opts->{image} || !exists $opts->{text} ? "Gtk2::$class"->new :
	  delete $opts->{mnemonic} ? "Gtk2::$class"->new_with_label(delete $opts->{text}) :
	    "Gtk2::$class"->new_with_mnemonic(delete $opts->{text});
    }

    $w->set_active(delete $opts->{active}) if exists $opts->{active};
    $w->signal_connect(toggled => delete $opts->{toggled}) if exists $opts->{toggled};
    $w;
}

sub _gtk___SpinButton {
    my ($w, $opts) = @_;

    if (!$w) {
	$opts->{adjustment} ||= do {
	    add2hash_($opts, { step_increment => 1, page_increment => 5, page_size => 1, value => delete $opts->{lower} });
	    Gtk2::Adjustment->new(delete $opts->{value}, delete $opts->{lower}, delete $opts->{upper}, delete $opts->{step_increment}, delete $opts->{page_increment}, delete $opts->{page_size});
	};
	$w = Gtk2::SpinButton->new(delete $opts->{adjustment}, delete $opts->{climb_rate} || 0, delete $opts->{digits} || 0);
    }

    $w->signal_connect(value_changed => delete $opts->{value_changed}) if exists $opts->{value_changed};
    $w;
}

sub _gtk__HScale {
    my ($w, $opts) = @_;

    if (!$w) {
	$opts->{adjustment} ||= do {
	    add2hash_($opts, { step_increment => 1, page_increment => 5, page_size => 1, value => delete $opts->{lower} });
	    Gtk2::Adjustment->new(delete $opts->{value}, delete $opts->{lower}, (delete $opts->{upper}) + 1, delete $opts->{step_increment}, delete $opts->{page_increment}, delete $opts->{page_size});
	};
	$w = Gtk2::HScale->new(delete $opts->{adjustment});
    }

    $w->signal_connect(value_changed => delete $opts->{value_changed}) if exists $opts->{value_changed};
    $w;
}

sub _gtk__VSeparator { &_gtk_any_simple }
sub _gtk__HSeparator { &_gtk_any_simple }
sub _gtk__Calendar   { &_gtk_any_simple }

sub _gtk__DrawingArea {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::DrawingArea->new;
    }
    $w->signal_connect(expose_event => delete $opts->{expose_event}) if exists $opts->{expose_event};
    $w;
}

sub _gtk__Pixbuf {
    my ($w, $opts) = @_;

    if (!$w) {
	my $name = delete $opts->{file} or internal_error("missing file");
	my $file = _find_imgfile($name) or internal_error("can not find $name");
	$w = Gtk2::Gdk::Pixbuf->new_from_file($file);
    }
    $w;
}

sub _gtk__Image {
    my ($w, $opts, $class) = @_;

    if (!$w) {
	$w = "Gtk2::$class"->new;
	$w->{format} = delete $opts->{format} if exists $opts->{format};
    }

    if (my $name = delete $opts->{file}) {
	my $file = _find_imgfile(may_apply($w->{format}, $name)) or internal_error("can not find $name");
	$w->set_from_file($file);
    } elsif (my $file_ref = delete $opts->{file_ref}) {
	my $set = sub {
	    my $file = _find_imgfile(may_apply($w->{format}, $$file_ref)) or internal_error("can not find $$file_ref");
	    $w->set_from_file($file);
	};
	gtkval_register($w, $file_ref, $set);
	$set->();
    }
    $w;
}

sub _gtk__WrappedLabel {
    my ($w, $opts) = @_;
    
    $opts->{line_wrap} = 1;
    _gtk__Label($w, $opts);
}

sub _gtk__Label {
    my ($w, $opts) = @_;

    if ($w) {
	$w->set_text(delete $opts->{text}) if exists $opts->{text};
    } else {
	$w = exists $opts->{text} ? Gtk2::Label->new(delete $opts->{text}) : Gtk2::Label->new;
	$w->set_justify(delete $opts->{justify}) if exists $opts->{justify};
	$w->set_line_wrap(delete $opts->{line_wrap}) if exists $opts->{line_wrap};
	$w->set_alignment(@{delete $opts->{alignment}}) if exists $opts->{alignment};
	$w->modify_font(Gtk2::Pango::FontDescription->from_string(delete $opts->{font})) if exists $opts->{font};
    }

    $w->set_markup(delete $opts->{text_markup}) if exists $opts->{text_markup};
    $w;
}

sub _gtk__Entry {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::Entry->new;
	$w->set_editable(delete $opts->{editable}) if exists $opts->{editable};
    }

    $w->set_text(delete $opts->{text}) if exists $opts->{text};
    $w->signal_connect(key_press_event => delete $opts->{key_press_event}) if exists $opts->{key_press_event};
    $w;
}

sub _gtk__TextView {
    my ($w, $opts) = @_;
	
    if (!$w) {
	$w = Gtk2::TextView->new;
	$w->set_editable(delete $opts->{editable}) if exists $opts->{editable};
	$w->set_wrap_mode(delete $opts->{wrap_mode}) if exists $opts->{wrap_mode};
	$w->set_cursor_visible(delete $opts->{cursor_visible}) if exists $opts->{cursor_visible};
    }

    _text_insert($w, delete $opts->{text}) if exists $opts->{text};
    $w;
}

sub _gtk__ComboBox {
    my ($w, $opts, $_class, $action) = @_;

    if (!$w) {
	$w = Gtk2::ComboBox->new_text;
	$w->{format} = delete $opts->{format} if exists $opts->{format};

    }
    if (exists $opts->{list}) {
	$w->{list} = delete $opts->{list};
	$w->{formatted_list} = $w->{format} ? [ map { $w->{format}($_) } @{$w->{list}} ] : $w->{list};
	$w->append_text($_) foreach @{$w->{formatted_list}};
    }

    if ($action eq 'gtknew') {
	if (my $text_ref = delete $opts->{text_ref}) {
	    my $set = sub {
		my $val = may_apply($w->{format}, $$text_ref);
		eval { $w->set_active(find_index { $_ eq $val } @{$w->{formatted_list}}) };
	    };
	    $w->signal_connect(changed => sub {
		gtkval_modify($text_ref, $w->{list}[$w->get_active], $set);
	    });
	    gtkval_register($w, $text_ref, $set);
	    gtkval_register($w, $text_ref, delete $opts->{changed}) if exists $opts->{changed};
	    $set->();
	} else {
	    my $val = delete $opts->{text};
	    eval { $w->set_active(find_index { $_ eq $val } @{$w->{formatted_list}}) } if defined $val;
	    $w->signal_connect(changed => delete $opts->{changed}) if exists $opts->{changed};
	}
    }
    $w;
}

sub _gtk__ScrolledWindow {
    my ($w, $opts, $_class, $action) = @_;
	
    if (!$w) {
	$w = Gtk2::ScrolledWindow->new(undef, undef);
	$w->set_policy(delete $opts->{h_policy} || 'automatic', delete $opts->{v_policy} || 'automatic');
    }

    if (my $child = delete $opts->{child}) {
	if (member(ref($child), qw(Gtk2::Layout Gtk2::Text Gtk2::TextView Gtk2::TreeView))) {
	    $w->add($child);
	} else {
	    $w->add_with_viewport($child);
	}
	$child->set_focus_vadjustment($w->get_vadjustment) if $child->can('set_focus_vadjustment');
	$child->set_left_margin(6) if ref($child) =~ /Gtk2::TextView/;
	$child->show;

	$w->child->set_shadow_type(delete $opts->{shadow_type}) if exists $opts->{shadow_type};

	if ($action eq 'gtknew' && ref($child) =~ /Gtk2::TextView|Gtk2::TreeView/) {
	    $w = gtknew('Frame', shadow_type => 'in', child => $w);
	}
    }
    $w;
}

sub _gtk__Frame {
    my ($w, $opts) = @_;

    if ($w) {
	$w->set_label(delete $opts->{text}) if exists $opts->{text};
    } else {
	$w = Gtk2::Frame->new(delete $opts->{text});
	$w->set_border_width(delete $opts->{border_width}) if exists $opts->{border_width};
	$w->set_shadow_type(delete $opts->{shadow_type}) if exists $opts->{shadow_type};
    }

    if (my $child = delete $opts->{child}) {
	$w->add($child);
	$child->show;
    }
    $w;
}

sub _gtk__Window {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::Window->new(delete $opts->{type} || 'toplevel');
	$w->set_modal(delete $opts->{modal}) if exists $opts->{modal};
	$w->set_border_width(delete $opts->{border_width}) if exists $opts->{border_width};
	$w->set_shadow_type(delete $opts->{shadow_type}) if exists $opts->{shadow_type};
    }
    $w->set_title(delete $opts->{title}) if exists $opts->{title};

    if (my $child = delete $opts->{child}) {
	$w->add($child);
	$child->show;
    }
    $w;
}

sub _gtk__Dialog {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::Dialog->new;

	$w->set_modal(delete $opts->{modal}) if exists $opts->{modal};
	$w->set_border_width(delete $opts->{border_width}) if exists $opts->{border_width};
	$w->set_transient_for(delete $opts->{transient_for}) if exists $opts->{transient_for};
	$w->set_position(delete $opts->{position_policy}) if exists $opts->{position_policy};
    }
    $w->set_title(delete $opts->{title}) if exists $opts->{title};

    $w;
}

sub _gtk__FileSelection {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::FileSelection->new(delete $opts->{title} || '');
	gtkset($w->ok_button, %{delete $opts->{ok_button}}) if exists $opts->{ok_button};
	gtkset($w->cancel_button, %{delete $opts->{cancel_button}}) if exists $opts->{cancel_button};
    }
    $w;
}

sub _gtk__VBox { &_gtk_any_Box }
sub _gtk__HBox { &_gtk_any_Box }
sub _gtk_any_Box {
    my ($w, $opts, $class, $action) = @_;

    if (!$w) {
	$w = "Gtk2::$class"->new(0,0);
	$w->set_homogeneous(delete $opts->{homogenous}) if exists $opts->{homogenous};
	$w->set_spacing(delete $opts->{spacing}) if exists $opts->{spacing};
	$w->set_border_width(delete $opts->{border_width}) if exists $opts->{border_width};
    } elsif ($action eq 'gtkset') {
	$_->destroy foreach $w->get_children;
    }

    _gtknew_handle_children($w, $opts);
    $w;
}

sub _gtk__VButtonBox { &_gtk_any_ButtonBox }
sub _gtk__HButtonBox { &_gtk_any_ButtonBox }
sub _gtk_any_ButtonBox {
    my ($w, $opts, $class, $action) = @_;

    if (!$w) {
	$w = "Gtk2::$class"->new;
	$w->set_layout(delete $opts->{layout} || 'spread');
    } elsif ($action eq 'gtkset') {
	$_->destroy foreach $w->get_children;
    }

    _gtknew_handle_children($w, $opts);
    $w;
}

sub _gtk__Notebook {
    my ($w, $opts) = @_;

    if (!$w) {
	$w = Gtk2::Notebook->new;
	$w->set_property('show-tabs', delete $opts->{show_tabs}) if exists $opts->{show_tabs};
	$w->set_property('show-border', delete $opts->{show_border}) if exists $opts->{show_border};
    }

    if (exists $opts->{children}) {
	foreach (group_by2(@{delete $opts->{children}})) {
	    my ($title, $page) = @$_;
	    $w->append_page($page, $title);
	    $page->show;
	    $title->show;
	}
    }
    $w;
}

sub _gtk__Table {
    my ($w, $opts) = @_;

    if (!$w) {
	add2hash_($opts, { xpadding => 5, ypadding => 0, border_width => $::isInstall ? 3 : 10 });

	$w = Gtk2::Table->new(0, 0, delete $opts->{homogeneous} || 0);
	$w->set_col_spacings(delete $opts->{col_spacings} || 0);
	$w->set_row_spacings(delete $opts->{row_spacings} || 0);
	$w->set_border_width(delete $opts->{border_width});
	$w->{$_} = delete $opts->{$_} foreach 'xpadding', 'ypadding', 'mcc';
    }

    each_index {
	my ($i, $l) = ($::i, $_);
	each_index {
	    my $j = $::i;
	    if ($_) {
		ref $_ or $_ = Gtk2::WrappedLabel->new($_);
		$j != $#$l && !$w->{mcc} ?
		  $w->attach($_, $j, $j + 1, $i, $i + 1,
			     'fill', 'fill', $w->{xpadding}, $w->{ypadding}) :
			       $w->attach($_, $j, $j + 1, $i, $i + 1,
					  ['expand', 'fill'], ref($_) eq 'Gtk2::ScrolledWindow' || $_->get_data('must_grow') ? ['expand', 'fill'] : [], 0, 0);
		$_->show;
	    }
	} @$l;
    } @{delete $opts->{children} || []};

    $w;
}

sub _gtk_any_simple {
    my ($w, $_opts, $class) = @_;

    $w ||= "Gtk2::$class"->new;
}

sub _gtknew_handle_children {
    my ($w, $opts) = @_;

    my @child = exists $opts->{children_tight} ? map { [ 0, $_ ] } @{delete $opts->{children_tight}} :
                exists $opts->{children_loose} ? map { [ 1, $_ ] } @{delete $opts->{children_loose}} :
	        exists $opts->{children} ? group_by2(@{delete $opts->{children}}) : ();

    foreach (@child) {
	my ($fill, $child) = @$_;
	$fill eq '0' || $fill eq '1' or internal_error("odd {children} parameter must be 0 or 1 (got $fill)");
	ref $child or $child = Gtk2::WrappedLabel->new($child);
	$w->pack_start($child, $fill, $fill, 0);
	$child->show;
    }
}

sub _find_imgfile {
    my ($name) = @_;