package GCE::MainWindow; =head1 NAME GCE::MainWindow - the main window class for gce =cut use Gtk2; use Gtk2::Gdk::Keysyms; use Gtk2::SimpleMenu; use Crossfire; use Crossfire::MapWidget; use GCE::AttrEdit; use Glib::Object::Subclass Gtk2::Window, signals => { update_stack_view => { return_type => undef, param_types => [Glib::Int, Glib::Int, Glib::Scalar] }, }; use strict; sub delete_arch { my ($self, $x, $y) = @_; return 0 unless defined $self->{map}; my $s = map_pop_tile_stack ($self->{map}, $x, $y); $self->{map}->update_map ($x, $y, 1, 1); } sub get_top_arch { my ($self, $x, $y) = @_; return 0 unless defined $self->{map}; map_get_tile_stack ($self->{map}, $self->{map}->coord ($x, $y))->[-1] } sub place_pick { my ($self, $x, $y) = @_; return 0 unless defined $self->{map} and defined $self->{pick_arch}; my $s = map_get_tile_stack ($self->{map}, $x, $y); my $top = $s->[-1]; my $arch = { _name => $self->{pick_arch}->{_name} }; if ($top->{_name} ne $arch->{_name}) { map_push_tile_stack ($self->{map}, $x, $y, $arch); } $self->{map}->update_map ($x, $y, 1, 1); } sub INIT_INSTANCE { my ($self) = @_; $self->signal_connect ('delete-event' => sub { Gtk2->main_quit; }); $self->set_title ("gce - main window"); my $menu_tree = [ _File => { item_type => '', children => [ _New => { callback => sub { $self->new_cb }, accelerator => 'N' }, _Open => { callback => sub { $self->open_cb }, accelerator => 'O' }, _Quit => { callback => sub { Gtk2->main_quit }, accelerator => 'Q' } ] }, _Edit => { item_type => '', children => [ _Fill => { callback => sub { die "NO IMPL" }, accelerator => "F" }, "Clear _Top" => { callback => sub { die "NO IMPL" }, accelerator => "T" }, "_Clear All" => { callback => sub { die "NO IMPL" }, accelerator => "C" }, "_Attributes" => { callback => sub { return if defined $self->{attr_edit}; my $w = Gtk2::Window->new; $w->set_title ("gce - edit attrs"); $w->add ($self->{attr_edit} = GCE::AttrEdit->new); $w->signal_connect ('delete-event' => sub { delete $self->{attr_edit} }); $w->show_all; }, accelerator => "A" }, "Open _Picker" => { callback => sub { my $p = GCE::PickWindow->new ( set_sel_cb => sub { $self->update_pick ($_[0]) }, arch_edit_cb => sub { $self->{attr_edit} and $self->{attr_edit}->set_arch ($_[0]) } ); $p->init; }, accelerator => "P" }, ] } ]; my $men = Gtk2::SimpleMenu->new ( menu_tree => $menu_tree, default_callback => \&default_cb, ); $self->add (my $vb = Gtk2::VBox->new); $vb->pack_start ($men->{widget}, 0, 1, 0); $vb->pack_start (my $lbl = Gtk2::Label->new ("no selection"), 0, 1, 0); $self->{pick_view} = $lbl; $self->add_accel_group ($men->{accel_group}); my $map = new Crossfire::MapWidget; # XXX:load $ARGV _cleanly_? my $path = $ARGV[0] || "$Crossfire::LIB/maps/dragonisland/advguild3"; $map->set_map (arch2map read_arch $path); $self->{map} = $map; $map->signal_connect (button_press_event => sub { my ($map, $event) = @_; my ($x, $y) = $map->coord ($event->x, $event->y); if ($event->button == 1) { $map->disable_tooltip unless $self->{draw_mode}; $self->{draw_mode} = [1, $x, $y]; $self->place_pick ($x, $y); return 1; } elsif ($event->button == 3) { $map->disable_tooltip unless $self->{draw_mode}; $self->{draw_mode} = [2, $x, $y]; $self->delete_arch ($x, $y); return 1; } 0 }); $map->signal_connect_after (motion_notify_event => sub { my ($map, $event) = @_; return unless $self->{draw_mode}; my ($X, $Y) = @{$self->{draw_mode}}[1,2]; my ($x, $y) = $map->coord ($map->get_pointer); while ($x != $X || $y != $Y) { $X++ if $X < $x; $X-- if $X > $x; $Y++ if $Y < $y; $Y-- if $Y > $y; if ($self->{draw_mode}[0] == 1) { $self->place_pick ($X, $Y); } elsif ($self->{draw_mode}[0] == 2) { $self->delete_arch ($X, $Y); } } @{$self->{draw_mode}}[1,2] = ($X, $Y); 1 }); $map->signal_connect (button_release_event => sub { my ($map, $event) = @_; $map->enable_tooltip if delete $self->{draw_mode}; if ($event->button == 1 && $event->state * "shift-mask") { return 0 unless defined $self->{attr_edit}; $self->{attr_edit}->set_arch ($self->get_top_arch ($event->x, $event->y)); return 1; } 0 }); $vb->pack_start ($map, 1, 1, 0); } sub new_cb { my ($self) = @_; die "NOT IMPLEMENTED YET"; } sub open_cb { my ($self) = @_; my $fc = Gtk2::FileChooserDialog->new ( 'Open map', undef, 'open', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok' ); $fc->add_shortcut_folder ("$Crossfire::LIB/maps"); $fc->set_current_folder ($self->{fc_last_folder} || "$Crossfire::LIB/maps"); if ('ok' eq $fc->run) { my $map = arch2map read_arch $fc->get_filename; $self->{fc_last_folder} = $fc->get_current_folder; $self->{map}->set_map ($map); $self->{map}->hide; $self->{map}->show_all; } $fc->destroy; } sub update_pick { my ($self, $arch) = @_; $self->{pick_arch} = $arch; $self->{pick_view}->set_text ($arch->{_name}); } =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ Robin Redeker http://www.ta-sa.org/ =cut 1;