ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MapEditor.pm
Revision: 1.4
Committed: Sat Feb 11 01:23:07 2006 UTC (18 years, 4 months ago) by elmex
Branch: MAIN
Changes since 1.3: +43 -47 lines
Log Message:
implemented the stackview

File Contents

# User Rev Content
1 elmex 1.1 package GCE::MapEditor;
2    
3     =head1 NAME
4    
5     GCE::MapEditor - the map editing widget
6    
7     =cut
8    
9     use Gtk2;
10     use Gtk2::Gdk::Keysyms;
11     use Gtk2::SimpleMenu;
12    
13     use Crossfire;
14 root 1.3 use Crossfire::Map;
15 elmex 1.1 use Crossfire::MapWidget;
16    
17     use GCE::AttrEdit;
18    
19 elmex 1.4 use Glib::Object::Subclass
20     Gtk2::VBox,
21     ;
22 elmex 1.1
23     use strict;
24    
25     sub INIT_INSTANCE {
26     my ($self) = @_;
27    
28     my $map = new Crossfire::MapWidget;
29    
30     # XXX: Make a nicer pick-view (with picture)
31     $self->pack_start (my $lbl = Gtk2::Label->new ("no selection"), 0, 1, 0);
32     $self->{pick_view} = $lbl;
33    
34     $self->pack_start ($map, 1, 1, 0);
35     $self->{map} = $map;
36    
37 elmex 1.4 $map->signal_connect (key_press_event => sub {
38     my ($map, $event) = @_;
39    
40     $event->keyval == $Gtk2::Gdk::Keysyms{Shift_L}
41     and $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_QUESTION_ARROW'));
42    
43     $event->keyval == $Gtk2::Gdk::Keysyms{Control_L}
44     and $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_HAND2'));
45    
46     });
47    
48     # XXX: What happens if the release got lost?
49     $map->signal_connect (key_release_event => sub {
50     my ($map, $event) = @_;
51    
52     $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
53    
54     });
55 elmex 1.1 $map->signal_connect (button_press_event => sub {
56     my ($map, $event) = @_;
57    
58     my ($x, $y) = $map->coord ($event->x, $event->y);
59    
60 elmex 1.4 if ($event->button == 1) {
61 elmex 1.1
62 elmex 1.4 my $s = map_get_tile_stack ($self->{map}, $x, $y);
63 elmex 1.1
64 elmex 1.4 if ($event->state * "control-mask") {
65 elmex 1.1
66 elmex 1.4 $self->update_pick ($s->[-1]) if @$s;
67 elmex 1.1 }
68    
69 elmex 1.4 unless ($event->state * "shift-mask") {
70 elmex 1.1
71     $map->disable_tooltip unless $self->{draw_mode};
72     $self->{draw_mode} = [1, $x, $y];
73     $self->place_pick ($x, $y);
74 elmex 1.4 $s = map_get_tile_stack ($self->{map}, $x, $y);
75     }
76    
77     $GCE::MainWindow::MAINWIN->update_attr_editor ($s->[-1]) if @$s;
78     $GCE::MainWindow::MAINWIN->update_stack_view ($self, $s, $x, $y);
79 elmex 1.1
80 elmex 1.4 return 1;
81 elmex 1.1
82 elmex 1.4 } elsif ($event->button == 3) {
83 elmex 1.1
84 elmex 1.4 $map->disable_tooltip unless $self->{draw_mode};
85     $self->{draw_mode} = [2, $x, $y];
86     $self->delete_arch ($x, $y);
87    
88     my $s = map_get_tile_stack ($self->{map}, $x, $y);
89     $GCE::MainWindow::MAINWIN->update_attr_editor ($s->[-1]) if @$s;
90     $GCE::MainWindow::MAINWIN->update_stack_view ($self, $s, $x, $y);
91 elmex 1.1
92 elmex 1.4 return 1;
93 elmex 1.1 }
94    
95     0
96     });
97    
98     $map->signal_connect_after (motion_notify_event => sub {
99     my ($map, $event) = @_;
100    
101     $self->{draw_mode}
102     or return;
103    
104     my ($X, $Y) = @{$self->{draw_mode}}[1,2];
105     my ($x, $y) = $map->coord ($map->get_pointer);
106    
107     while ($x != $X || $y != $Y) {
108    
109     $X++ if $X < $x;
110     $X-- if $X > $x;
111     $Y++ if $Y < $y;
112     $Y-- if $Y > $y;
113    
114     if ($self->{draw_mode}[0] == 1) {
115    
116     $self->place_pick ($X, $Y);
117    
118     } elsif ($self->{draw_mode}[0] == 2) {
119    
120     $self->delete_arch ($X, $Y);
121     }
122     }
123    
124     @{$self->{draw_mode}}[1,2] = ($X, $Y);
125    
126     1
127     });
128    
129     $map->signal_connect (button_release_event => sub {
130     my ($map, $event) = @_;
131    
132     $map->enable_tooltip if delete $self->{draw_mode};
133    
134     0
135     });
136     }
137    
138 root 1.3 sub set_place_arch {
139     my ($self, $arch) = @_;
140    
141     $self->{pick_arch} = $arch;
142     }
143    
144     sub delete_arch {
145     my ($self, $x, $y) = @_;
146    
147     defined $self->{map}
148     or return 0;
149    
150     my $s = map_pop_tile_stack ($self->{map}, $x, $y);
151     $self->{map}->update_map ($x, $y, 1, 1);
152     }
153    
154     sub place_pick {
155     my ($self, $x, $y) = @_;
156    
157     defined $self->{map}
158     and defined $self->{pick_arch}
159     or return 0;
160    
161     my $s = map_get_tile_stack ($self->{map}, $x, $y);
162 elmex 1.4
163     # XXX: Do a deep clone?
164 root 1.3 my $arch = { _name => $self->{pick_arch}->{_name} };
165    
166     if (not defined ($s->[-1]) or $s->[-1]->{_name} ne $arch->{_name}) {
167    
168     map_push_tile_stack ($self->{map}, $x, $y, $arch);
169     }
170    
171     $self->{map}->update_map ($x, $y, 1, 1);
172     }
173    
174     sub open_map {
175     my ($self, $path) = @_;
176    
177     $self->{map}->set_map (new_from_file Crossfire::Map $path);
178     }
179    
180 elmex 1.1 sub update_pick {
181     my ($self, $arch) = @_;
182    
183     $self->{pick_arch} = $arch;
184     $self->{pick_view}->set_text ($arch->{_name});
185     }
186    
187     =head1 AUTHOR
188    
189     Marc Lehmann <schmorp@schmorp.de>
190     http://home.schmorp.de/
191    
192     Robin Redeker <elmex@ta-sa.org>
193     http://www.ta-sa.org/
194    
195     =cut
196     1;
197