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.29 by elmex, Mon Mar 20 04:11:41 2006 UTC vs.
Revision 1.35 by elmex, Tue Apr 4 11:29:54 2006 UTC

19 19
20use Glib::Object::Subclass 20use Glib::Object::Subclass
21 Gtk2::Window; 21 Gtk2::Window;
22 22
23use strict; 23use strict;
24
25sub do_context_menu {
26 my ($self, $map, $event) = @_;
27
28 my ($x, $y) = $map->coord ($event->x, $event->y);
29
30 my $menu = Gtk2::Menu->new;
31 foreach my $cm (
32 [
33 Follow => sub {
34 $::MAINWIN->{edit_collection}{followexit}->begin ($map, $x, $y, $self)
35 }
36 ]
37 ) {
38 my $item = Gtk2::MenuItem->new ($cm->[0]);
39 $menu->append ($item);
40 $item->show;
41 $item->signal_connect (activate => $cm->[1]);
42 }
43 $menu->popup (undef, undef, undef, undef, $event->button, $event->time);
44}
24 45
25sub build_menu { 46sub build_menu {
26 my ($self) = @_; 47 my ($self) = @_;
27 48
28 my $menu_tree = [ 49 my $menu_tree = [
34 accelerator => '<ctrl>S' 55 accelerator => '<ctrl>S'
35 }, 56 },
36 "Save As" => { 57 "Save As" => {
37 callback => sub { $self->save_map_as }, 58 callback => sub { $self->save_map_as },
38 }, 59 },
60 "_Map Properties" => {
61 callback => sub { $self->open_map_prop },
62 accelerator => "<ctrl>P"
63 },
64 "_Map Resize" => {
65 callback => sub { $self->open_resize_map },
66 accelerator => "<ctrl>R"
67 },
39 "Close" => { 68 "Close" => {
40 callback => sub { $self->delete; 1 }, 69 callback => sub { $self->destroy },
41 }, 70 },
42 ] 71 ]
43 }, 72 },
44 _Edit => { 73 _Edit => {
45 item_type => '<Branch>', 74 item_type => '<Branch>',
50 }, 79 },
51 "_Redo" => { 80 "_Redo" => {
52 callback => sub { $self->redo }, 81 callback => sub { $self->redo },
53 accelerator => "<ctrl>Y" 82 accelerator => "<ctrl>Y"
54 }, 83 },
55 "_Map Properties" => {
56 callback => sub { $self->open_map_prop },
57 accelerator => "<ctrl>P"
58 },
59 "_Map Resize" => {
60 callback => sub { $self->open_resize_map },
61 accelerator => "<ctrl>R"
62 },
63 ] 84 ]
64 }, 85 },
65 _Go => { 86 _Go => {
66 item_type => '<Branch>', 87 item_type => '<Branch>',
67 children => [ 88 children => [
68 "_Up" => { 89 "_Up" => {
69 callback => sub { $self->follow ('u') }, 90 callback => sub { $self->follow ('u') },
70 accelerator => "<ctrl>U" 91 accelerator => "<ctrl>Up"
71 }, 92 },
72 "_Down" => { 93 "_Down" => {
73 callback => sub { $self->follow ('d') }, 94 callback => sub { $self->follow ('d') },
74 accelerator => "<ctrl>D" 95 accelerator => "<ctrl>Down"
75 }, 96 },
76 "_Right" => { 97 "_Right" => {
77 callback => sub { $self->follow ('r') }, 98 callback => sub { $self->follow ('r') },
78 accelerator => "<ctrl>R" 99 accelerator => "<ctrl>Right"
79 }, 100 },
80 "_Left" => { 101 "_Left" => {
81 callback => sub { $self->follow ('l') }, 102 callback => sub { $self->follow ('l') },
82 accelerator => "<ctrl>L" 103 accelerator => "<ctrl>Left"
83 }, 104 },
84 ] 105 ]
85 }, 106 },
86 _Help => { 107 _Help => {
87 item_type => '<Branch>', 108 item_type => '<Branch>',
88 children => [ 109 children => [
89 _Help => { 110 _Manual => {
90 callback => sub { $::MAINWIN->show_help_window }, 111 callback => sub { $::MAINWIN->show_help_window },
91 accelerator => "<ctrl>H" 112 accelerator => "<ctrl>H"
92 }, 113 },
93 ] 114 ]
94 }, 115 },
118 $self->add_accel_group ($men->{accel_group}); 139 $self->add_accel_group ($men->{accel_group});
119 140
120 return $men->{widget}; 141 return $men->{widget};
121} 142}
122 143
144sub set_edit_tool {
145 my ($self, $tool) = @_;
146
147 $self->{etool} = $tool;
148
149 if ($self->ea->special_arrow) {
150 $self->{map}{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow));
151 } else {
152 # FIXME: Get the original cursor and insert it here
153 $self->{map}{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
154 }
155}
156
123sub ea { 157sub ea {
124 my ($self) = @_; 158 my ($self) = @_;
125 $self->{ea_alt} || $::MAINWIN->{sel_editaction}; 159 $self->{ea_alt} || $self->{etool};
126} 160}
127 161
128sub INIT_INSTANCE { 162sub INIT_INSTANCE {
129 my ($self) = @_; 163 my ($self) = @_;
130 164
131 $self->set_title ('gce - map editor'); 165 $self->set_title ('gce - map editor');
132 $self->add (my $vb = Gtk2::VBox->new); 166 $self->add (my $vb = Gtk2::VBox->new);
133 167
134 $self->signal_connect (delete_event => sub { $self->delete; 1 });
135
136 $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0); 168 $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0);
137 169
138 $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0); 170 $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0);
139 171
140 $self->signal_connect (focus_in_event => sub {
141 my $ea = $::MAINWIN->{sel_editaction};
142 if ($ea->special_arrow) {
143 $self->{map}->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($ea->special_arrow));
144 } else {
145 $self->{map}->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
146 }
147 delete $self->{ea_alt};
148 });
149
150 $map->signal_connect (key_press_event => sub { 172 $map->signal_connect_after (key_press_event => sub {
151 my ($map, $event) = @_; 173 my ($map, $event) = @_;
152 174
153 my $kv = $event->keyval; 175 my $kv = $event->keyval;
176
177 my $ret = 0;
154 178
155 my ($x, $y) = $map->coord ($map->get_pointer); 179 my ($x, $y) = $map->coord ($map->get_pointer);
156 for ([Control_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{erase} }], 180 for ([Control_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{erase} }],
157 [Alt_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{pick} }], 181 [Alt_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{pick} }],
158 [c => sub { $::MAINWIN->{edit_collection}{select}->copy }], 182 [c => sub { $::MAINWIN->{edit_collection}{select}->copy }],
159 [v => sub { $::MAINWIN->{edit_collection}{select}->paste ($map, $x, $y) }], 183 [v => sub { $::MAINWIN->{edit_collection}{select}->paste ($map, $x, $y) }],
160 [n => sub { $::MAINWIN->{edit_collection}{select}->invoke }], 184 [n => sub { $::MAINWIN->{edit_collection}{select}->invoke }],
161 ) 185 )
162 { 186 {
187 my $ed = $_;
188
163 if ($kv == $Gtk2::Gdk::Keysyms{$_->[0]}) { 189 if ($kv == $Gtk2::Gdk::Keysyms{$ed->[0]}) {
190 my $was_in_draw = defined $self->{draw_mode};
191
192 $self->stop_drawmode ($map)
193 if $was_in_draw && grep { $ed->[0] eq $_ } qw/Control_L Alt_L/;
194
164 $_->[1]->(); 195 $ed->[1]->();
196 $ret = 1;
197
198 $self->start_drawmode ($map)
199 if $was_in_draw && grep { $ed->[0] eq $_ } qw/Control_L Alt_L/;
165 } 200 }
166 } 201 }
167 202
168 if ($self->ea->special_arrow) { 203 if ($self->ea->special_arrow) {
169 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow)); 204 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow));
170 } 205 } else {
206 # FIXME: Get the original cursor and insert it here
207 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
171 1; 208 }
209
210 $ret
172 }); 211 });
212
173 $map->signal_connect (key_release_event => sub { 213 $map->signal_connect_after (key_release_event => sub {
174 my ($map, $event) = @_; 214 my ($map, $event) = @_;
215
216 my $ret = 0;
175 217
176 if ($event->keyval == $Gtk2::Gdk::Keysyms{Control_L} 218 if ($event->keyval == $Gtk2::Gdk::Keysyms{Control_L}
177 or $event->keyval == $Gtk2::Gdk::Keysyms{Alt_L}) 219 or $event->keyval == $Gtk2::Gdk::Keysyms{Alt_L})
178 { 220 {
221 my $was_in_draw = defined $self->{draw_mode};
222
223 $self->stop_drawmode ($map)
224 if $was_in_draw;
225
179 delete $self->{ea_alt}; 226 delete $self->{ea_alt};
227 $ret = 1;
228
229 $self->start_drawmode ($map)
230 if $was_in_draw;
180 } 231 }
181 232
182 if ($self->ea->special_arrow) { 233 if ($self->ea->special_arrow) {
183 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow)); 234 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow));
184 } else { 235 } else {
185 # XXX: Get the original cursor and insert it here 236 # FIXME: Get the original cursor and insert it here
186 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR')); 237 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
187 } 238 }
188 1; 239
240 $ret
189 }); 241 });
190 $map->signal_connect (button_press_event => sub { 242 $map->signal_connect_after (button_press_event => sub {
191 my ($map, $event) = @_; 243 my ($map, $event) = @_;
192 244
193 my ($x, $y) = $map->coord ($event->x, $event->y);
194 my $as = $map->get ($x, $y);
195
196 if ((not $self->{draw_mode}) and $event->button != 2) { 245 if ((not $self->{draw_mode}) and $event->button == 1) {
197
198 my $ea = $self->ea; 246 my $ea = $self->ea;
199 247
200 $ea->begin ($map, $x, $y, $self) 248 $self->start_drawmode ($map);
201 if $x >= 0 and $y >= 0 and $x < $map->{map}{width} and $y < $map->{map}{height};
202
203 $self->{draw_mode} = [$x, $y];
204 249
205 $ea->want_cursor 250 $ea->want_cursor
206 or $map->disable_tooltip; 251 or $map->disable_tooltip;
207 252
208 return 1; 253 return 1;
254 } elsif ($event->button == 3) {
255 $self->do_context_menu ($map, $event);
256 return 1;
209 } 257 }
258
210 0 259 0
211 }); 260 });
212 261
213 $map->signal_connect_after (motion_notify_event => sub { 262 $map->signal_connect_after (motion_notify_event => sub {
214 my ($map, $event) = @_; 263 my ($map, $event) = @_;
235 @{$self->{draw_mode}}[0,1] = ($X, $Y); 284 @{$self->{draw_mode}}[0,1] = ($X, $Y);
236 285
237 1 286 1
238 }); 287 });
239 288
240 $map->signal_connect (button_release_event => sub { 289 $map->signal_connect_after (button_release_event => sub {
241 my ($map, $event) = @_; 290 my ($map, $event) = @_;
242 291
243 if ($self->{draw_mode}) { 292 if ($self->{draw_mode} and $event->button == 1) {
244 my ($x, $y) = $map->coord ($map->get_pointer);
245
246 my $ea = $self->ea; 293 my $ea = $self->ea;
247 $ea->end ($map, $x, $y, $self);
248 294
249 delete $self->{draw_mode}; 295 $self->stop_drawmode ($map);
250 296
251 $ea->want_cursor 297 $ea->want_cursor
252 or $map->enable_tooltip; 298 or $map->enable_tooltip;
253 299
254 return 1; 300 return 1;
255 } 301 }
256 302
257 0 303 0
258 }); 304 });
305}
306
307sub start_drawmode {
308 my ($self, $map) = @_;
309
310 $self->{draw_mode} and return;
311
312 # XXX: is this okay? my ($x, $y) = $map->coord ($event->x, $event->y);
313 my ($x, $y) = $map->coord ($map->get_pointer);
314
315 my $ea = $self->ea;
316
317 $ea->begin ($map, $x, $y, $self)
318 if $x >= 0 and $y >= 0 and $x < $map->{map}{width} and $y < $map->{map}{height};
319
320 $self->{draw_mode} = [$x, $y];
321}
322
323sub stop_drawmode {
324 my ($self, $map) = @_;
325
326 $self->{draw_mode} or return;
327
328 my ($x, $y) = $map->coord ($map->get_pointer);
329
330 my $ea = $self->ea;
331 $ea->end ($map, $x, $y, $self);
332
333 delete $self->{draw_mode};
259} 334}
260 335
261# FIXME: Fix the automatic update of the attribute editor! and also the stack view! 336# FIXME: Fix the automatic update of the attribute editor! and also the stack view!
262sub undo { 337sub undo {
263 my ($self) = @_; 338 my ($self) = @_;
278 $map->{undo_stack} 353 $map->{undo_stack}
279 and $map->{undo_stack_pos} < @{$map->{undo_stack}} 354 and $map->{undo_stack_pos} < @{$map->{undo_stack}}
280 or return; 355 or return;
281 356
282 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]); 357 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]);
283}
284
285sub delete {
286 my ($self) = @_;
287
288 # check and modla dialog if "dirty"
289
290 if ($self->{mapkey}) {
291 # XXX: This should be in a delete event handler in the MainWindow.pm... but it doesnt work
292 delete $::MAINWIN->{loaded_maps}->{$self->{mapkey}};
293 }
294
295 $self->destroy;
296} 358}
297 359
298sub open_map { 360sub open_map {
299 my ($self, $path, $key) = @_; 361 my ($self, $path, $key) = @_;
300 362

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines