… | |
… | |
8 | |
8 | |
9 | use Gtk2; |
9 | use Gtk2; |
10 | use Gtk2::Gdk::Keysyms; |
10 | use Gtk2::Gdk::Keysyms; |
11 | use Gtk2::SimpleMenu; |
11 | use Gtk2::SimpleMenu; |
12 | |
12 | |
13 | use Crossfire; |
13 | use Deliantra; |
14 | use Crossfire::Map; |
14 | use Deliantra::Map; |
15 | use Crossfire::MapWidget; |
15 | use Deliantra::MapWidget; |
16 | |
16 | |
17 | use GCE::AttrEdit; |
17 | use GCE::AttrEdit; |
18 | use GCE::Util; |
18 | use GCE::Util; |
19 | use GCE::HashDialog; |
19 | use GCE::HashDialog; |
20 | |
20 | |
… | |
… | |
121 | }, |
121 | }, |
122 | "Map _Attachments" => { |
122 | "Map _Attachments" => { |
123 | callback => sub { $self->open_attach_edit }, |
123 | callback => sub { $self->open_attach_edit }, |
124 | accelerator => "<ctrl>A" |
124 | accelerator => "<ctrl>A" |
125 | }, |
125 | }, |
126 | "Map Meta _Info" => { |
126 | # "Map Meta _Info" => { |
127 | callback => sub { $self->open_meta_info }, |
127 | # callback => sub { $self->open_meta_info }, |
128 | }, |
128 | # }, |
129 | Upload => { |
129 | # Upload => { |
130 | item_type => '<Branch>', |
130 | # item_type => '<Branch>', |
131 | children => [ |
131 | # children => [ |
132 | "Upload for testing" => { |
132 | # "Upload for testing" => { |
133 | callback => sub { $self->upload_map_test }, |
133 | # callback => sub { $self->upload_map_test }, |
134 | }, |
134 | # }, |
135 | "Upload for inclusion" => { |
135 | # "Upload for inclusion" => { |
136 | callback => sub { $self->upload_map_incl }, |
136 | # callback => sub { $self->upload_map_incl }, |
137 | }, |
137 | # }, |
138 | ] |
138 | # ] |
139 | }, |
139 | # }, |
140 | "_Map Resize" => { |
140 | "_Map Resize" => { |
141 | callback => sub { $self->open_resize_map }, |
141 | callback => sub { $self->open_resize_map }, |
142 | }, |
142 | }, |
143 | "Close" => { |
143 | "Close" => { |
144 | callback => sub { $self->destroy }, |
144 | callback => sub { $self->destroy }, |
|
|
145 | accelerator => "<ctrl>W", |
145 | }, |
146 | }, |
146 | ] |
147 | ] |
147 | }, |
148 | }, |
148 | _Edit => { |
149 | _Edit => { |
149 | item_type => '<Branch>', |
150 | item_type => '<Branch>', |
… | |
… | |
297 | |
298 | |
298 | # FIXME: Fix the automatic update of the attribute editor! and also the stack view! |
299 | # FIXME: Fix the automatic update of the attribute editor! and also the stack view! |
299 | sub undo { |
300 | sub undo { |
300 | my ($self) = @_; |
301 | my ($self) = @_; |
301 | |
302 | |
302 | my $map = $self->{map}; # the Crossfire::MapWidget |
303 | my $map = $self->{map}; # the Deliantra::MapWidget |
303 | |
304 | |
304 | $map->{undo_stack_pos} |
305 | $map->{undo_stack_pos} |
305 | or return; |
306 | or return; |
306 | |
307 | |
307 | $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]); |
308 | $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]); |
|
|
309 | |
|
|
310 | $::MAINWIN->update_stack_view (); |
308 | } |
311 | } |
309 | |
312 | |
310 | sub get_stack_refs { |
313 | sub get_stack_refs { |
311 | my ($self, $map, $x, $y) = @_; |
314 | my ($self, $map, $x, $y) = @_; |
312 | |
315 | |
… | |
… | |
315 | return [] unless @$cstack; |
318 | return [] unless @$cstack; |
316 | |
319 | |
317 | my @refs; |
320 | my @refs; |
318 | |
321 | |
319 | for my $arch (@$cstack) { |
322 | for my $arch (@$cstack) { |
320 | my ($ox, $oy) = ($x, $y); |
323 | my ($ix, $iy, $iarch, $istack) = devirtualize ($map, $x, $y, $arch, $cstack); |
321 | if ($arch->{_virtual}) { |
|
|
322 | $ox = $arch->{virtual_x}; |
|
|
323 | $oy = $arch->{virtual_y}; |
|
|
324 | $arch = $arch->{_virtual}; |
|
|
325 | $cstack = $map->get ($ox, $oy); |
|
|
326 | # XXX: This heavily blows up if $arch isn't on $cstack now.. and it actually really does :( |
|
|
327 | } |
|
|
328 | |
|
|
329 | push @refs, |
324 | push @refs, |
330 | GCE::ArchRef->new ( |
325 | GCE::ArchRef->new ( |
331 | arch => $arch, |
326 | arch => $iarch, |
332 | source => 'map', |
327 | source => 'map', |
333 | cb => sub { |
328 | cb => sub { |
334 | $map->change_begin ('attredit'); |
329 | $map->change_begin ('attredit'); |
335 | $map->change_stack ($ox, $oy, $cstack); |
330 | $map->change_stack ($ix, $iy, $istack); |
336 | |
331 | |
337 | if (my $changeset = $map->change_end) { |
332 | if (my $changeset = $map->change_end) { |
338 | splice @{ $map->{undo_stack} ||= [] }, |
333 | splice @{ $map->{undo_stack} ||= [] }, |
339 | $map->{undo_stack_pos}++, 1e6, |
334 | $map->{undo_stack_pos}++, 1e6, |
340 | $changeset; |
335 | $changeset; |
… | |
… | |
347 | } |
342 | } |
348 | |
343 | |
349 | sub redo { |
344 | sub redo { |
350 | my ($self) = @_; |
345 | my ($self) = @_; |
351 | |
346 | |
352 | my $map = $self->{map}; # the Crossfire::MapWidget |
347 | my $map = $self->{map}; # the Deliantra::MapWidget |
353 | |
348 | |
354 | $map->{undo_stack} |
349 | $map->{undo_stack} |
355 | and $map->{undo_stack_pos} < @{$map->{undo_stack}} |
350 | and $map->{undo_stack_pos} < @{$map->{undo_stack}} |
356 | or return; |
351 | or return; |
357 | |
352 | |
… | |
… | |
362 | my ($mapfile) = @_; |
357 | my ($mapfile) = @_; |
363 | if (-e "$mapfile.meta") { |
358 | if (-e "$mapfile.meta") { |
364 | open my $metafh, "<", "$mapfile.meta" |
359 | open my $metafh, "<", "$mapfile.meta" |
365 | or warn "Couldn't open meta file $mapfile.meta: $!"; |
360 | or warn "Couldn't open meta file $mapfile.meta: $!"; |
366 | my $metadata = do { local $/; <$metafh> }; |
361 | my $metadata = do { local $/; <$metafh> }; |
367 | return Crossfire::from_json ($metadata); |
362 | return Deliantra::decode_json ($metadata); |
368 | } |
363 | } |
369 | } |
364 | } |
370 | |
365 | |
371 | sub save_meta_info { |
366 | sub save_meta_info { |
372 | my ($mapfile, $metainfo) = @_; |
367 | my ($mapfile, $metainfo) = @_; |
373 | open my $metafh, ">", "$mapfile.meta" |
368 | open my $metafh, ">", "$mapfile.meta" |
374 | or warn "Couldn't write meta file $mapfile.meta: $!"; |
369 | or warn "Couldn't write meta file $mapfile.meta: $!"; |
375 | print $metafh Crossfire::to_json ($metainfo); |
370 | print $metafh Deliantra::encode_json ($metainfo); |
376 | } |
371 | } |
377 | |
372 | |
378 | sub open_map { |
373 | sub open_map { |
379 | my ($self, $path, $key) = @_; |
374 | my ($self, $path, $key) = @_; |
380 | |
375 | |
381 | $self->{mapkey} = $key; |
376 | $self->{mapkey} = $key; |
382 | |
377 | |
383 | if (ref $path) { |
378 | if (ref $path) { |
384 | $self->{map}->set_map ($path); |
379 | $self->{map}->set_map ($path); |
385 | delete $self->{meta_info}; |
380 | delete $self->{meta_info}; |
386 | $self->set_title ('<ram>'); |
381 | $self->set_window_title; |
387 | |
382 | |
388 | } else { |
383 | } else { |
389 | my $ok = 0; |
384 | my $ok = 0; |
390 | if (-e $path && -f $path) { |
385 | if (-e $path && -f $path) { |
391 | $ok = 1; |
386 | $ok = 1; |
… | |
… | |
399 | } |
394 | } |
400 | unless ($ok) { |
395 | unless ($ok) { |
401 | die "Couldn't open '$path' or find '$path.map': No such file or it is not a file.\n"; |
396 | die "Couldn't open '$path' or find '$path.map': No such file or it is not a file.\n"; |
402 | } |
397 | } |
403 | $self->{path} = $path; |
398 | $self->{path} = $path; |
404 | $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path); |
399 | $self->{map}->set_map (my $m = new_from_file Deliantra::Map $path); |
405 | $self->{meta_info} = load_meta_info ($path); |
400 | $self->{meta_info} = load_meta_info ($path); |
406 | $self->set_title ("gce - map editor - $self->{path}"); |
401 | $self->set_window_title ($self->{path}); |
|
|
402 | $::MAINWIN->add_recent($path); |
407 | } |
403 | } |
|
|
404 | $self->update_overlays; |
408 | $self->close_windows; |
405 | $self->close_windows; |
409 | } |
406 | } |
410 | |
407 | |
411 | sub save_map { |
408 | sub save_map { |
412 | my ($self) = @_; |
409 | my ($self) = @_; |
… | |
… | |
415 | $self->{map}{map}->write_file ($self->{path}); |
412 | $self->{map}{map}->write_file ($self->{path}); |
416 | if ($self->{meta_info}) { |
413 | if ($self->{meta_info}) { |
417 | save_meta_info ($self->{path}, $self->{meta_info}); |
414 | save_meta_info ($self->{path}, $self->{meta_info}); |
418 | } |
415 | } |
419 | quick_msg ($self, "saved to $self->{path}"); |
416 | quick_msg ($self, "saved to $self->{path}"); |
420 | $self->set_title ("gce - map editor - $self->{path}"); |
417 | $self->set_window_title ($self->{path}); |
|
|
418 | $::MAINWIN->add_recent($self->{path}); |
421 | } else { |
419 | } else { |
422 | $self->save_map_as; |
420 | $self->save_map_as; |
423 | } |
421 | } |
424 | } |
422 | } |
425 | |
423 | |
|
|
424 | sub set_window_title { |
|
|
425 | my ($self, $title) = @_; |
|
|
426 | |
|
|
427 | $title = 'Unsaved' |
|
|
428 | unless $title; |
|
|
429 | |
|
|
430 | $self->set_title(File::Basename::basename($title).' - deliantra editor'); |
|
|
431 | } |
|
|
432 | |
426 | sub save_map_as { |
433 | sub save_map_as { |
427 | my ($self) = @_; |
434 | my ($self) = @_; |
428 | |
435 | |
429 | my $fc = $::MAINWIN->new_filechooser ('gce - save map', 1, $self->{path}); |
436 | my $fc = $::MAINWIN->new_filechooser ('gce - save map', 1, $self->{path}); |
430 | |
437 | |
431 | if ('ok' eq $fc->run) { |
438 | if ('ok' eq $fc->run) { |
432 | |
439 | |
433 | $::MAINWIN->{fc_last_folder} = $fc->get_current_folder; |
440 | $::MAINWIN->{fc_last_folder} = $fc->get_current_folder; |
434 | $::MAINWIN->{fc_last_folders}->{$self->{fc_last_folder}}++; |
441 | $::MAINWIN->{fc_last_folders}->{$self->{fc_last_folder}}++; |
435 | |
442 | |
436 | $self->{map}{map}->write_file ($self->{path} = $fc->get_filename); |
443 | if($fc->get_filename) { |
437 | if ($self->{meta_info}) { |
444 | $self->{path} = $fc->get_filename; |
438 | save_meta_info ($self->{path}, $self->{meta_info}); |
445 | $self->save_map; |
439 | } |
446 | } |
440 | quick_msg ($self, "saved to $self->{path}"); |
|
|
441 | $self->set_title ("gce - map editor - $self->{path}"); |
|
|
442 | } |
447 | } |
443 | |
448 | |
444 | $fc->destroy; |
449 | $fc->destroy; |
|
|
450 | } |
|
|
451 | |
|
|
452 | sub _get_conns_for_obj { |
|
|
453 | my ($obj, $x, $y, $rconns) = @_; |
|
|
454 | |
|
|
455 | if (defined $obj->{connected}) { |
|
|
456 | $rconns->{$x}->{$y}->{$obj->{connected}} = 1; |
|
|
457 | |
|
|
458 | } elsif (defined $obj->{msg}) { |
|
|
459 | my $msg = $obj->{msg}; |
|
|
460 | |
|
|
461 | while ($msg =~ s/\@trigger\s+(\d+)//) { |
|
|
462 | $rconns->{$x}->{$y}->{$1} = 1; |
|
|
463 | } |
|
|
464 | } |
|
|
465 | } |
|
|
466 | |
|
|
467 | sub update_overlays { |
|
|
468 | my ($self, $sx, $sy, $stack) = @_; |
|
|
469 | my $conns = {}; |
|
|
470 | |
|
|
471 | if (not $stack) { |
|
|
472 | my ($w, $h) = ($self->{map}{map}{width}, $self->{map}{map}{height}); |
|
|
473 | |
|
|
474 | for (my $x = 0; $x < $w; $x++) { |
|
|
475 | for (my $y = 0; $y < $h; $y++) { |
|
|
476 | _get_conns_for_obj ($_, $x, $y, $conns) |
|
|
477 | for @{$self->{map}->get_ro ($x, $y)}; |
|
|
478 | } |
|
|
479 | } |
|
|
480 | |
|
|
481 | # delete prev. overlays |
|
|
482 | for (keys %{$self->{_conn_overlays}}) { |
|
|
483 | $self->{map}->overlay ($_); |
|
|
484 | } |
|
|
485 | } else { |
|
|
486 | # del old overlay for this place |
|
|
487 | my $ovl = "connection_$sx\_$sy"; |
|
|
488 | $self->{map}->overlay ($ovl) if delete $self->{_conn_overlays}->{$ovl}; |
|
|
489 | _get_conns_for_obj ($_, $sx, $sy, $conns) |
|
|
490 | for @$stack; |
|
|
491 | } |
|
|
492 | |
|
|
493 | # put new overlays there |
|
|
494 | for my $x (keys %$conns) { |
|
|
495 | for my $y (keys %{$conns->{$x}}) { |
|
|
496 | my $ovlname = "connection_$x\_$y"; |
|
|
497 | my $conns_ovl = join (', ', keys %{$conns->{$x}->{$y}}); |
|
|
498 | $self->{_conn_overlays}->{$ovlname} = 1; |
|
|
499 | my ($a, $t, $ac) |
|
|
500 | = Gtk2::Pango->parse_markup ( |
|
|
501 | "<span size=\"xx-small\">$conns_ovl</span>", '' |
|
|
502 | ); |
|
|
503 | my $pl = $self->{map}->create_pango_layout (''); |
|
|
504 | $pl->set_attributes ($a); |
|
|
505 | $pl->set_text ($t); |
|
|
506 | my ($ink_rect, $logical_rect) = $pl->get_pixel_extents; |
|
|
507 | |
|
|
508 | $self->{map}->overlay ( |
|
|
509 | $ovlname, $x * TILESIZE, $y * TILESIZE, TILESIZE, TILESIZE, |
|
|
510 | sub { |
|
|
511 | my ($mapwin, $x, $y) = @_; |
|
|
512 | if (!$self->{_conn_upd_ovl_gc_fg}) { |
|
|
513 | my $gc |
|
|
514 | = $self->{_conn_upd_ovl_gc_fg} |
|
|
515 | = Gtk2::Gdk::GC->new ($mapwin->{window}); |
|
|
516 | my $cm = $mapwin->{window}->get_colormap; |
|
|
517 | $gc->set_foreground (gtk2_get_color ($mapwin, "yellow")); |
|
|
518 | $gc->set_background (gtk2_get_color ($mapwin, "black")); |
|
|
519 | } |
|
|
520 | $mapwin->{window}->draw_rectangle ( |
|
|
521 | $mapwin->style->black_gc, |
|
|
522 | 1, |
|
|
523 | $x, $y, $logical_rect->{width} + 2, $logical_rect->{height} + 2, |
|
|
524 | ); |
|
|
525 | $mapwin->{window}->draw_rectangle ( |
|
|
526 | $self->{_conn_upd_ovl_gc_fg}, |
|
|
527 | 0, |
|
|
528 | $x, $y, $logical_rect->{width} + 2, $logical_rect->{height} + 2, |
|
|
529 | ); |
|
|
530 | $mapwin->{window}->draw_layout_with_colors ( |
|
|
531 | $mapwin->style->black_gc, $x + 1, $y + 1, $pl, |
|
|
532 | $self->{connection_overlay_foreground}, |
|
|
533 | $self->{connection_overlay_background}, |
|
|
534 | ) |
|
|
535 | } |
|
|
536 | ); |
|
|
537 | } |
|
|
538 | } |
445 | } |
539 | } |
446 | |
540 | |
447 | ################################################################# |
541 | ################################################################# |
448 | ###### DIALOGOUES ############################################### |
542 | ###### DIALOGOUES ############################################### |
449 | ################################################################# |
543 | ################################################################# |
… | |
… | |
462 | ref_hash => $self->{map}{map}{info}, |
556 | ref_hash => $self->{map}{map}{info}, |
463 | dialog => [ |
557 | dialog => [ |
464 | [width => 'Width' => 'string'], |
558 | [width => 'Width' => 'string'], |
465 | [height => 'Height' => 'string'], |
559 | [height => 'Height' => 'string'], |
466 | ], |
560 | ], |
467 | close_on_save => 1, |
561 | close_on_save => 1, |
|
|
562 | save_button_label => 'resize', |
468 | save_cb => sub { |
563 | save_cb => sub { |
469 | my ($info) = @_; |
564 | my ($info) = @_; |
470 | $self->{map}{map}->resize ($info->{width}, $info->{height}); |
565 | $self->{map}{map}->resize ($info->{width}, $info->{height}); |
471 | $self->{map}->invalidate_all; |
566 | $self->{map}->set_map ($self->{map}{map}); |
|
|
567 | $self->update_overlays; |
472 | } |
568 | } |
473 | ); |
569 | ); |
474 | |
570 | |
475 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
571 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
476 | |
572 | |
… | |
… | |
518 | [path => 'Map path' => 'string'], |
614 | [path => 'Map path' => 'string'], |
519 | ], |
615 | ], |
520 | close_on_save => 1, |
616 | close_on_save => 1, |
521 | save_cb => sub { |
617 | save_cb => sub { |
522 | my ($meta) = @_; |
618 | my ($meta) = @_; |
523 | warn "UPLOAD[".Crossfire::to_json ($meta)."]\n"; |
619 | warn "UPLOAD[".Deliantra::encode_json ($meta)."]\n"; |
524 | } |
620 | } |
525 | ); |
621 | ); |
526 | |
622 | |
527 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
623 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
528 | |
624 | |
… | |
… | |
549 | [cf_password=> 'Password' => 'password'], |
645 | [cf_password=> 'Password' => 'password'], |
550 | [path => 'Map path' => 'string'], |
646 | [path => 'Map path' => 'string'], |
551 | ], |
647 | ], |
552 | save_cb => sub { |
648 | save_cb => sub { |
553 | my ($meta) = @_; |
649 | my ($meta) = @_; |
554 | warn "UPLOAD[".Crossfire::to_json ($meta)."]\n"; |
650 | warn "UPLOAD[".Deliantra::encode_json ($meta)."]\n"; |
555 | } |
651 | } |
556 | ); |
652 | ); |
557 | |
653 | |
558 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
654 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
559 | |
655 | |
… | |
… | |
593 | sub open_map_info { |
689 | sub open_map_info { |
594 | my ($self) = @_; |
690 | my ($self) = @_; |
595 | return if $self->{map_info}; |
691 | return if $self->{map_info}; |
596 | |
692 | |
597 | my $w = $self->{map_info} = Gtk2::Window->new ('toplevel'); |
693 | my $w = $self->{map_info} = Gtk2::Window->new ('toplevel'); |
598 | $w->set_title ("gcrossedit - map info"); |
694 | $w->set_title ("deliantra editor - map info"); |
599 | |
695 | |
600 | $w->add (my $vb = Gtk2::VBox->new); |
696 | $w->add (my $vb = Gtk2::VBox->new); |
601 | $vb->add (my $sw = Gtk2::ScrolledWindow->new); |
697 | $vb->add (my $sw = Gtk2::ScrolledWindow->new); |
602 | $sw->set_policy ('automatic', 'automatic'); |
698 | $sw->set_policy ('automatic', 'automatic'); |
603 | $sw->add (my $txt = Gtk2::TextView->new); |
699 | $sw->add (my $txt = Gtk2::TextView->new); |
… | |
… | |
701 | ################################################################# |
797 | ################################################################# |
702 | |
798 | |
703 | sub INIT_INSTANCE { |
799 | sub INIT_INSTANCE { |
704 | my ($self) = @_; |
800 | my ($self) = @_; |
705 | |
801 | |
706 | $self->set_title ('gce - map editor'); |
802 | $self->set_window_title; |
707 | $self->add (my $vb = Gtk2::VBox->new); |
803 | $self->add (my $vb = Gtk2::VBox->new); |
708 | |
804 | |
709 | $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0); |
805 | $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0); |
710 | |
806 | |
711 | $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0); |
807 | $vb->pack_start (my $map = $self->{map} = Deliantra::MapWidget->new, 1, 1, 0); |
|
|
808 | |
|
|
809 | $map->signal_connect_after (stack_change => sub { |
|
|
810 | my ($map, $x, $y, $stack) = @_; |
|
|
811 | $self->update_overlays ($x, $y, $stack); |
|
|
812 | $::MAINWIN->update_map_pos ($self, $x, $y); |
|
|
813 | }); |
|
|
814 | $map->signal_connect_after (swap_stack_change => sub { |
|
|
815 | my ($map, $x, $y, $stack) = @_; |
|
|
816 | $self->update_overlays ($x, $y, $stack); |
|
|
817 | $::MAINWIN->update_map_pos ($self, $x, $y); |
|
|
818 | }); |
|
|
819 | |
|
|
820 | $self->{connection_overlay_foreground} |
|
|
821 | = Gtk2::Gdk::Color->new (257 * 255, 257 * 255, 0); |
|
|
822 | $self->{connection_overlay_background} |
|
|
823 | = Gtk2::Gdk::Color->new (0, 0, 0); |
|
|
824 | # my $ygc |
|
|
825 | # = $self->{connection_overlay_yellow_gc} |
|
|
826 | # = Gtk2::Gdk::GC->new ($self->{map}{window}); |
|
|
827 | # $ygc->set_foreground (Gtk2::Gdk::Color->new (257 * 255, 257 * 255, 0)); |
712 | |
828 | |
713 | $map->signal_connect_after (key_press_event => sub { |
829 | $map->signal_connect_after (key_press_event => sub { |
714 | my ($map, $event) = @_; |
830 | my ($map, $event) = @_; |
715 | |
831 | |
716 | my $kv = $event->keyval; |
832 | my $kv = $event->keyval; |
717 | |
833 | |
718 | my $ret = 0; |
834 | my $ret = 0; |
719 | |
835 | |
720 | my ($x, $y) = $map->coord ($map->get_pointer); |
836 | my ($x, $y) = $map->coord ($map->get_pointer); |
721 | for ([Control_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{erase} }], |
|
|
722 | [Alt_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{pick} }], |
|
|
723 | [c => sub { $::MAINWIN->{edit_collection}{select}->copy }], |
837 | for ([c => sub { $::MAINWIN->{edit_collection}{select}->copy }], |
724 | [v => sub { $::MAINWIN->{edit_collection}{select}->paste ($map, $x, $y) }], |
838 | [v => sub { $::MAINWIN->{edit_collection}{select}->paste ($map, $x, $y) }], |
725 | [n => sub { $::MAINWIN->{edit_collection}{select}->invoke }], |
839 | [n => sub { $::MAINWIN->{edit_collection}{select}->invoke }], |
726 | ) |
840 | ) |
727 | { |
841 | { |
728 | my $ed = $_; |
842 | my $ed = $_; |
729 | |
843 | |
730 | if ($kv == $Gtk2::Gdk::Keysyms{$ed->[0]}) { |
844 | if ($kv == $Gtk2::Gdk::Keysyms{$ed->[0]}) { |
731 | my $was_in_draw = defined $self->{draw_mode}; |
845 | my $was_in_draw = defined $self->{draw_mode}; |
732 | |
846 | |
733 | $self->stop_drawmode ($map) |
847 | $self->stop_drawmode ($map) if $was_in_draw; |
734 | if $was_in_draw && grep { $ed->[0] eq $_ } qw/Control_L Alt_L/; |
|
|
735 | |
848 | |
736 | $ed->[1]->(); |
849 | $ed->[1]->(); |
737 | $ret = 1; |
850 | $ret = 1; |
738 | |
851 | |
739 | $self->start_drawmode ($map) |
852 | $self->start_drawmode ($map) if $was_in_draw; |
740 | if $was_in_draw && grep { $ed->[0] eq $_ } qw/Control_L Alt_L/; |
|
|
741 | } |
853 | } |
742 | } |
854 | } |
743 | |
855 | |
744 | if ($self->ea->special_arrow) { |
856 | if ($self->ea->special_arrow) { |
745 | $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow)); |
857 | $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow)); |
… | |
… | |
749 | } |
861 | } |
750 | |
862 | |
751 | $ret |
863 | $ret |
752 | }); |
864 | }); |
753 | |
865 | |
754 | $map->signal_connect_after (key_release_event => sub { |
|
|
755 | my ($map, $event) = @_; |
|
|
756 | |
|
|
757 | my $ret = 0; |
|
|
758 | |
|
|
759 | if ($event->keyval == $Gtk2::Gdk::Keysyms{Control_L} |
|
|
760 | or $event->keyval == $Gtk2::Gdk::Keysyms{Alt_L}) |
|
|
761 | { |
|
|
762 | my $was_in_draw = defined $self->{draw_mode}; |
|
|
763 | |
|
|
764 | $self->stop_drawmode ($map) |
|
|
765 | if $was_in_draw; |
|
|
766 | |
|
|
767 | delete $self->{ea_alt}; |
|
|
768 | $ret = 1; |
|
|
769 | |
|
|
770 | $self->start_drawmode ($map) |
|
|
771 | if $was_in_draw; |
|
|
772 | } |
|
|
773 | |
|
|
774 | if ($self->ea->special_arrow) { |
|
|
775 | $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow)); |
|
|
776 | } else { |
|
|
777 | # FIXME: Get the original cursor and insert it here |
|
|
778 | $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR')); |
|
|
779 | } |
|
|
780 | |
|
|
781 | $ret |
|
|
782 | }); |
|
|
783 | $map->signal_connect_after (button_press_event => sub { |
866 | $map->signal_connect_after (button_press_event => sub { |
784 | my ($map, $event) = @_; |
867 | my ($map, $event) = @_; |
785 | |
868 | |
786 | if ((not $self->{draw_mode}) and $event->button == 1) { |
869 | if ((not $self->{draw_mode}) and $event->button == 1) { |
787 | my $ea = $self->ea; |
870 | my $ea = $self->ea; |