ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MapEditor.pm
(Generate patch)

Comparing deliantra/gde/GCE/MapEditor.pm (file contents):
Revision 1.73.2.2 by elmex, Tue Jul 7 15:42:18 2009 UTC vs.
Revision 1.73.2.3 by elmex, Mon Dec 21 15:51:30 2009 UTC

3=head1 NAME 3=head1 NAME
4 4
5 GCE::MapEditor - the map editing widget 5 GCE::MapEditor - the map editing widget
6 6
7=cut 7=cut
8
9use Devel::FindRef;
8 10
9use Gtk2; 11use Gtk2;
10use Gtk2::Gdk::Keysyms; 12use Gtk2::Gdk::Keysyms;
11use Gtk2::SimpleMenu; 13use Gtk2::SimpleMenu;
12 14
25 27
26use Scalar::Util qw/weaken/; 28use Scalar::Util qw/weaken/;
27use Storable qw/dclone/; 29use Storable qw/dclone/;
28 30
29use Guard; 31use Guard;
32
33use AnyEvent;
30 34
31use strict; 35use strict;
32 36
33################################################################# 37#################################################################
34###### WINDOW MANAGEMENT ######################################## 38###### WINDOW MANAGEMENT ########################################
77 } 81 }
78 82
79 $menu->append (my $sep = new Gtk2::SeparatorMenuItem); 83 $menu->append (my $sep = new Gtk2::SeparatorMenuItem);
80 $sep->show; 84 $sep->show;
81 85
82 for my $sr (reverse $self->get_stack_refs ($map, $x, $y)) { 86 my $curs = $self->cursor ("context menu at ($x,$y)", $x, $y);
87
88 for (my $z = 0; $z < $curs->size; $z++) {
89 my $ar = $curs->cursor ($z);
90
83 my $item = Gtk2::MenuItem->new ($sr->longname); 91 my $item = Gtk2::MenuItem->new ($ar->longname);
84 $menu->append ($item); 92 $menu->append ($item);
85 $item->set_submenu (my $smenu = new Gtk2::Menu); 93 $item->set_submenu (my $smenu = new Gtk2::Menu);
86 94
87 for my $act ( 95 for my $act (
88 [ 'Add inventory' => sub { $_[0]->add_inv ($::MAINWIN->get_pick) } ], 96 [ 'Add inventory' => sub { $ar->push ($::MAINWIN->get_pick) } ],
89 [ 'Find in picker' => sub { $::MAINWIN->open_pick_window ({ selection => $sr->picker_folder }) } ], 97 [ 'Find in picker' =>
98 sub {
99 $::MAINWIN->open_pick_window (
100 { selection => $ar->picker_folder })
101 }
102 ],
90 ) { 103 ) {
91 my $sitem = Gtk2::MenuItem->new ($act->[0]); 104 my $sitem = Gtk2::MenuItem->new ($act->[0]);
92 $smenu->append ($sitem); 105 $smenu->append ($sitem);
93 $sitem->signal_connect (activate => sub { $act->[1]->($sr) }); 106 $sitem->signal_connect (activate => $act->[1]);
94 $sitem->show; 107 $sitem->show;
95 } 108 }
96 109
97 $item->show; 110 $item->show;
98 } 111 }
308 $map->{undo_stack_pos} 321 $map->{undo_stack_pos}
309 or return; 322 or return;
310 323
311 $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]); 324 $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]);
312 325
313 $::MAINWIN->update_stack_view (); 326 $self->invalidate_cursors ('undo');
314}
315
316sub get_stack_refs {
317 my ($self, $map, $x, $y) = @_;
318
319 my $cstack = $map->get ($x, $y);
320
321 return [] unless @$cstack;
322
323 my @refs;
324
325 for my $arch (@$cstack) {
326 my ($ix, $iy, $iarch, $istack) = devirtualize ($map, $x, $y, $arch, $cstack);
327 push @refs,
328 GCE::ArchRef->new (
329 arch => $iarch,
330 source => 'map',
331 cb => sub {
332 $map->change_begin ('attredit');
333 $map->change_stack ($ix, $iy, $istack);
334
335 if (my $changeset = $map->change_end) {
336 splice @{ $map->{undo_stack} ||= [] },
337 $map->{undo_stack_pos}++, 1e6,
338 $changeset;
339 }
340 }
341 );
342 }
343
344 return @refs;
345} 327}
346 328
347sub redo { 329sub redo {
348 my ($self) = @_; 330 my ($self) = @_;
349 331
350 my $map = $self->{map}; # the Deliantra::MapWidget 332 my $map = $self->{map}; # the Deliantra::MapWidget
351 333
352 $map->{undo_stack} 334 $map->{undo_stack}
353 and $map->{undo_stack_pos} < @{$map->{undo_stack}} 335 and $map->{undo_stack_pos} < @{$map->{undo_stack}}
354 or return; 336 or return;
355 337
356 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]); 338 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]);
339
340 $self->invalidate_cursors ('redo');
357} 341}
358 342
359sub load_meta_info { 343sub load_meta_info {
360 my ($mapfile) = @_; 344 my ($mapfile) = @_;
361 if (-e "$mapfile.meta") { 345 if (-e "$mapfile.meta") {
799################################################################# 783#################################################################
800###### CURSORS ################################################## 784###### CURSORS ##################################################
801################################################################# 785#################################################################
802 786
803sub cursor { 787sub cursor {
804 my ($self, $owner, $x, $y, $z, @inv_path) = @_; 788 my ($self, $x, $y) = @_;
805 789
806 my $cursmap = ($self->{_cursors} ||= []); 790 my $cursmap = ($self->{_cursors} ||= []);
807 my $cursor; 791 my $cursor = $cursmap->[$x]->[$y];
808 792
809 weaken $self; 793 weaken $self;
810 794
811 #d# warn "NEWCURSOR $x, $y, ($owner)\n"; 795 #d# warn "NEWCURSOR $x, $y, ($owner)\n";
812 796
797 unless ($cursor) {
813 eval { 798 eval {
814 $cursor = GCE::ArchRef->new ( 799 $cursor = GCE::StackRef->new (src => [$self, $x, $y]);
815 x => $x, 800 $cursmap->[$x]->[$y] = $cursor;
816 y => $y,
817 map => $self,
818 owner => $owner
819 ); 801 };
820 push @{$cursmap->[$x]->[$y]}, $cursor
821 };
822 if ($@) { 802 if ($@) {
823 if ($@ =~ /bad arch cursor/) { 803 if ($@ =~ /bad arch cursor/) {
824 #d# warn "BAD CURSOR $x, $y, $owner\n"; 804 #d# warn "BAD CURSOR $x, $y, $owner\n";
825 return undef; 805 return undef;
826 } else { 806 } else {
827 die $@; 807 die $@;
828 } 808 }
829 } 809 }
830 810
831 #d# warn "ADDED CURSOR $owner, $x, $y, => [$cursor] " . (1 * $cursor) . "\n"; 811 #d# warn "ADDED CURSOR $owner, $x, $y, => [$cursor] " . (1 * $cursor) . "\n";
832 812
833 weaken $cursmap->[$x]->[$y]->[-1]; 813 weaken $cursmap->[$x]->[$y];
834
835 $cursor->{z} = $z if defined $z;
836 $cursor->{inv} = \@inv_path if @inv_path;
837
838 my ($cx, $cy, $cid) = ($cursor->{x}, $cursor->{y}, 1 * $cursor);
839 $cursor->{guard} = guard {
840 if ($cid == $self->{_last_attr_edit_overlay_cid}) {
841 $self->{map}->overlay ('attr_edit');
842 }
843 }; 814 }
844 815
816#d# my $cu = $cursor;
817#d# weaken $cu;
818#d#
819#d# my $n = "$cursor";
820#d#
821#d# my $tv;
822#d# $tv = AE::timer 1, 1, sub {
823#d# if ($cu) {
824#d# warn "OVERLAYREFALIV! $n: " . (Devel::FindRef::track \$cu) . "\n";
825#d# } else {
826#d# undef $tv;
827#d# }
828#d# };
829
845 $self->update_cursor_overlay ($cursor); 830# $self->update_cursor_overlay ($cursor);
846 $cursor 831 $cursor
847} 832}
848 833
849sub cursors_at { 834sub cursor_at {
850 my ($self, $x, $y) = @_; 835 my ($self, $x, $y) = @_;
851 my $cursmap = ($self->{_cursors} ||= []); 836 my $cursmap = ($self->{_cursors} ||= []);
852 $cursmap->[$x]->[$y] || [] 837 $cursmap->[$x]->[$y]
853} 838}
854 839
855sub update_cursor_overlay { 840sub invalidate_cursors {
856 my ($self, $cursor) = @_; 841 my ($self, $act) = @_;
857 842
858 if ($cursor->{owner} eq 'attr_edit') { 843 for my $cols (@{$self->{_cursors}}) {
859 $self->{_last_attr_edit_overlay_cid} = 1 * $cursor; 844 for my $curs (grep { defined $_ } @$cols) {
860 845 $curs->changed ($act || 'some_invalidation', 1);
861 $self->{map}->overlay (attr_edit =>
862 $cursor->{x} * TILESIZE,
863 $cursor->{y} * TILESIZE,
864 TILESIZE,
865 TILESIZE,
866 sub {
867 my ($self, $x, $y) = @_;
868
869 if (!$self->{_conn_upd_curs_gc_fg}) {
870 my $gc
871 = $self->{_conn_upd_curs_gc_fg}
872 = Gtk2::Gdk::GC->new ($self->{window});
873 my $cm = $self->{window}->get_colormap;
874 $gc->set_foreground (gtk2_get_color ($self, "green"));
875 $gc->set_background (gtk2_get_color ($self, "black"));
876 }
877
878 $self->{window}->draw_rectangle (
879 $_ & 1 ? $self->style->black_gc : $self->{_conn_upd_curs_gc_fg},
880 0,
881 $x + $_, $y + $_,
882 TILESIZE - 1 - $_ * 2,
883 TILESIZE - 1 - $_ * 2
884 ) for 0..3;
885 } 846 }
886 );
887 } 847 }
888}
889 848
849 $self->{_cursors} = [];
850}
890 851
891################################################################# 852#################################################################
892###### MAP EDITOR INIT ########################################## 853###### MAP EDITOR INIT ##########################################
893################################################################# 854#################################################################
894 855

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines