package GCE::MapEditor; =head1 NAME GCE::MapEditor - the map editing widget =cut use Gtk2; use Gtk2::Gdk::Keysyms; use Gtk2::SimpleMenu; use Crossfire; use Crossfire::Map; use Crossfire::MapWidget; use GCE::AttrEdit; use Glib::Object::Subclass Gtk2::Window; use strict; sub build_menu { my ($self) = @_; my $menu_tree = [ _File => { item_type => '', children => [ "_Save" => { callback => sub { $self->save_map }, accelerator => 'S' }, ] children => [ "Save As" => { callback => sub { $self->save_map_as }, }, ] }, _Edit => { item_type => '', children => [ "_Undo" => { callback => sub { $self->undo }, accelerator => "Z" }, "_Redo" => { callback => sub { $self->redo }, accelerator => "Y" }, ] }, ]; my $men = Gtk2::SimpleMenu->new ( menu_tree => $menu_tree, default_callback => \&default_cb, ); $self->add_accel_group ($men->{accel_group}); return $men->{widget}; } sub INIT_INSTANCE { my ($self) = @_; $self->set_title ('gce - map editor'); $self->add (my $vb = Gtk2::VBox->new); $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0); $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0); $map->signal_connect (button_press_event => sub { my ($map, $event) = @_; my ($x, $y) = $map->coord ($event->x, $event->y); my $as = $map->get ($x, $y); my $btn = $event->button; if ((not $self->{draw_mode}) and $btn != 2 and my $ea = $::MAINWIN->{sel_editaction}) { $ea->begin ($map, $x, $y, $btn); $self->{draw_mode} = [$ea, $x, $y, $btn]; $ea->want_cursor or $map->disable_tooltip; if ($ea->special_arrow) { $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($ea->special_arrow)); #'GDK_QUESTION_ARROW')); } return 1; } 0 }); $map->signal_connect_after (motion_notify_event => sub { my ($map, $event) = @_; $self->{draw_mode} or return; 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; $self->{draw_mode}[0]->edit ($map, $X, $Y, $self->{draw_mode}[3]); } @{$self->{draw_mode}}[1,2] = ($X, $Y); 1 }); $map->signal_connect (button_release_event => sub { my ($map, $event) = @_; if ($self->{draw_mode} and my $ea = $self->{draw_mode}[0] and $self->{draw_mode}[3] == $event->button) { my ($x, $y) = $map->coord ($map->get_pointer); $ea->end ($map, $x, $y, $event->button); if ($ea->special_arrow) { # XXX: Get the original cursor and insert it here $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR')); } delete $self->{draw_mode}; $ea->want_cursor or $map->enable_tooltip; return 1; } 0 }); } sub undo { my ($self) = @_; my $map = $self->{map}; # the Crossfire::MapWidget $map->{undo_stack_pos} or return; $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]); } sub redo { my ($self) = @_; my $map = $self->{map}; # the Crossfire::MapWidget $map->{undo_stack_pos} < @{$map->{undo_stack}} or return; $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]); } sub delete_arch { my ($self, $x, $y) = @_; defined $self->{map} or return 0; my $as = $self->{map}->get ($x, $y); pop @$as; $self->{map}->set ($x, $y, $as); } sub place_pick { my ($self, $x, $y) = @_; my $pick = $::MAINWIN->get_pick; my $as = $self->{map}->get ($x, $y); my $arch = { _name => $pick->{_name} }; push @$as, $arch unless @$as && $as->[-1]->{_name} eq $arch->{_name}; $self->{map}->set ($x, $y, $as); } sub open_map { my ($self, $path) = @_; $self->{map}->set_map (new_from_file Crossfire::Map $path); } =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ Robin Redeker http://www.ta-sa.org/ =cut 1;