… | |
… | |
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 | |
|
|
21 | use POSIX qw/strftime/; |
|
|
22 | |
21 | use Glib::Object::Subclass |
23 | use Glib::Object::Subclass |
22 | Gtk2::Window; |
24 | Gtk2::Window; |
23 | |
25 | |
24 | use Storable qw/dclone/; |
26 | use Storable qw/dclone/; |
25 | |
27 | |
… | |
… | |
33 | my ($self) = @_; |
35 | my ($self) = @_; |
34 | |
36 | |
35 | $self->{attach_editor}->save_layout if $self->{attach_editor}; |
37 | $self->{attach_editor}->save_layout if $self->{attach_editor}; |
36 | $self->{map_properties}->save_layout if $self->{map_properties}; |
38 | $self->{map_properties}->save_layout if $self->{map_properties}; |
37 | $self->{meta_info_win}->save_layout if $self->{meta_info_win}; |
39 | $self->{meta_info_win}->save_layout if $self->{meta_info_win}; |
|
|
40 | |
|
|
41 | $main::CFG->{map_info} = main::get_pos_and_size ($self->{map_info}) |
|
|
42 | if $self->{map_info}; |
38 | } |
43 | } |
39 | |
44 | |
40 | sub close_windows { |
45 | sub close_windows { |
41 | my ($self) = @_; |
46 | my ($self) = @_; |
42 | |
47 | |
… | |
… | |
66 | $menu->append ($item); |
71 | $menu->append ($item); |
67 | $item->show; |
72 | $item->show; |
68 | $item->signal_connect (activate => $cm->[1]); |
73 | $item->signal_connect (activate => $cm->[1]); |
69 | } |
74 | } |
70 | |
75 | |
71 | my $inv_item = Gtk2::MenuItem->new ("Add inventory"); |
76 | $menu->append (my $sep = new Gtk2::SeparatorMenuItem); |
72 | $inv_item->set_submenu (my $smenu = new Gtk2::Menu); |
77 | $sep->show; |
73 | $menu->append ($inv_item); |
|
|
74 | |
78 | |
75 | for my $sr (reverse $self->get_stack_refs ($map, $x, $y)) { |
79 | for my $sr (reverse $self->get_stack_refs ($map, $x, $y)) { |
76 | my $item = Gtk2::MenuItem->new ($sr->longname); |
80 | my $item = Gtk2::MenuItem->new ($sr->longname); |
77 | $smenu->append ($item); |
81 | $menu->append ($item); |
|
|
82 | $item->set_submenu (my $smenu = new Gtk2::Menu); |
|
|
83 | |
|
|
84 | for my $act ( |
|
|
85 | [ 'Add inventory' => sub { $_[0]->add_inv ($::MAINWIN->get_pick) } ], |
|
|
86 | [ 'Find in picker' => sub { $::MAINWIN->open_pick_window ({ selection => $sr->picker_folder }) } ], |
|
|
87 | ) { |
|
|
88 | my $sitem = Gtk2::MenuItem->new ($act->[0]); |
|
|
89 | $smenu->append ($sitem); |
|
|
90 | $sitem->signal_connect (activate => sub { $act->[1]->($sr) }); |
|
|
91 | $sitem->show; |
|
|
92 | } |
|
|
93 | |
78 | $item->show; |
94 | $item->show; |
79 | $item->signal_connect (activate => sub { |
|
|
80 | $sr->add_inv ($::MAINWIN->get_pick); |
|
|
81 | }); |
|
|
82 | } |
95 | } |
83 | |
96 | |
84 | $inv_item->show; |
|
|
85 | $menu->popup (undef, undef, undef, undef, $event->button, $event->time); |
97 | $menu->popup (undef, undef, undef, undef, $event->button, $event->time); |
86 | } |
98 | } |
87 | |
99 | |
88 | sub build_menu { |
100 | sub build_menu { |
89 | my ($self) = @_; |
101 | my ($self) = @_; |
… | |
… | |
96 | callback => sub { $self->save_map }, |
108 | callback => sub { $self->save_map }, |
97 | accelerator => '<ctrl>S' |
109 | accelerator => '<ctrl>S' |
98 | }, |
110 | }, |
99 | "Save As" => { |
111 | "Save As" => { |
100 | callback => sub { $self->save_map_as }, |
112 | callback => sub { $self->save_map_as }, |
|
|
113 | }, |
|
|
114 | "Map _Info" => { |
|
|
115 | callback => sub { $self->open_map_info }, |
|
|
116 | accelerator => "<ctrl>I", |
101 | }, |
117 | }, |
102 | "Map _Properties" => { |
118 | "Map _Properties" => { |
103 | callback => sub { $self->open_map_prop }, |
119 | callback => sub { $self->open_map_prop }, |
104 | accelerator => "<ctrl>P" |
120 | accelerator => "<ctrl>P" |
105 | }, |
121 | }, |
… | |
… | |
311 | } |
327 | } |
312 | |
328 | |
313 | push @refs, |
329 | push @refs, |
314 | GCE::ArchRef->new ( |
330 | GCE::ArchRef->new ( |
315 | arch => $arch, |
331 | arch => $arch, |
|
|
332 | source => 'map', |
316 | cb => sub { |
333 | cb => sub { |
317 | $map->change_begin ('attredit'); |
334 | $map->change_begin ('attredit'); |
318 | $map->change_stack ($ox, $oy, $cstack); |
335 | $map->change_stack ($ox, $oy, $cstack); |
319 | |
336 | |
320 | if (my $changeset = $map->change_end) { |
337 | if (my $changeset = $map->change_end) { |
… | |
… | |
361 | sub open_map { |
378 | sub open_map { |
362 | my ($self, $path, $key) = @_; |
379 | my ($self, $path, $key) = @_; |
363 | |
380 | |
364 | $self->{mapkey} = $key; |
381 | $self->{mapkey} = $key; |
365 | |
382 | |
366 | |
|
|
367 | if (ref $path) { |
383 | if (ref $path) { |
368 | $self->{map}->set_map ($path); |
384 | $self->{map}->set_map ($path); |
369 | delete $self->{meta_info}; |
385 | delete $self->{meta_info}; |
370 | $self->set_title ('<ram>'); |
386 | $self->set_title ('<ram>'); |
371 | |
387 | |
372 | } else { |
388 | } else { |
|
|
389 | my $ok = 0; |
|
|
390 | if (-e $path && -f $path) { |
|
|
391 | $ok = 1; |
|
|
392 | } else { |
|
|
393 | unless ($path =~ m/\.map$/) { # yuck |
|
|
394 | my $p = $path . '.map'; |
|
|
395 | if ($ok = -e $p && -f $p) { |
|
|
396 | $path = $p; |
|
|
397 | } |
|
|
398 | } |
|
|
399 | } |
|
|
400 | unless ($ok) { |
|
|
401 | die "Couldn't open '$path' or find '$path.map': No such file or it is not a file.\n"; |
|
|
402 | } |
373 | $self->{path} = $path; |
403 | $self->{path} = $path; |
374 | $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path); |
404 | $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path); |
375 | $self->{meta_info} = load_meta_info ($path); |
405 | $self->{meta_info} = load_meta_info ($path); |
376 | $self->set_title ("gce - map editor - $self->{path}"); |
406 | $self->set_title ("gce - map editor - $self->{path}"); |
377 | } |
407 | } |
… | |
… | |
432 | ref_hash => $self->{map}{map}{info}, |
462 | ref_hash => $self->{map}{map}{info}, |
433 | dialog => [ |
463 | dialog => [ |
434 | [width => 'Width' => 'string'], |
464 | [width => 'Width' => 'string'], |
435 | [height => 'Height' => 'string'], |
465 | [height => 'Height' => 'string'], |
436 | ], |
466 | ], |
|
|
467 | close_on_save => 1, |
437 | save_cb => sub { |
468 | save_cb => sub { |
438 | my ($info) = @_; |
469 | my ($info) = @_; |
439 | $self->{map}{map}->resize ($info->{width}, $info->{height}); |
470 | $self->{map}{map}->resize ($info->{width}, $info->{height}); |
440 | $self->{map}->invalidate_all; |
471 | $self->{map}->invalidate_all; |
441 | $w->destroy; |
|
|
442 | } |
472 | } |
443 | ); |
473 | ); |
444 | |
474 | |
445 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
475 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
446 | |
476 | |
… | |
… | |
485 | [undef => x => 'sep' ], |
515 | [undef => x => 'sep' ], |
486 | [cf_login => 'Server login name' => 'string'], |
516 | [cf_login => 'Server login name' => 'string'], |
487 | [cf_password=> 'Password' => 'password'], |
517 | [cf_password=> 'Password' => 'password'], |
488 | [path => 'Map path' => 'string'], |
518 | [path => 'Map path' => 'string'], |
489 | ], |
519 | ], |
|
|
520 | close_on_save => 1, |
490 | save_cb => sub { |
521 | save_cb => sub { |
491 | my ($meta) = @_; |
522 | my ($meta) = @_; |
492 | warn "UPLOAD[".Crossfire::to_json ($meta)."]\n"; |
523 | warn "UPLOAD[".Crossfire::to_json ($meta)."]\n"; |
493 | } |
524 | } |
494 | ); |
525 | ); |
… | |
… | |
557 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
588 | $w->signal_connect (destroy => sub { delete $self->{meta_info_win} }); |
558 | |
589 | |
559 | $w->show_all; |
590 | $w->show_all; |
560 | } |
591 | } |
561 | |
592 | |
|
|
593 | sub open_map_info { |
|
|
594 | my ($self) = @_; |
|
|
595 | return if $self->{map_info}; |
|
|
596 | |
|
|
597 | my $w = $self->{map_info} = Gtk2::Window->new ('toplevel'); |
|
|
598 | $w->set_title ("gcrossedit - map info"); |
|
|
599 | |
|
|
600 | $w->add (my $vb = Gtk2::VBox->new); |
|
|
601 | $vb->add (my $sw = Gtk2::ScrolledWindow->new); |
|
|
602 | $sw->set_policy ('automatic', 'automatic'); |
|
|
603 | $sw->add (my $txt = Gtk2::TextView->new); |
|
|
604 | $vb->pack_start (my $hb = Gtk2::HBox->new (1, 1), 0, 1, 0); |
|
|
605 | $hb->pack_start (my $svbtn = Gtk2::Button->new ("save"), 1, 1, 0); |
|
|
606 | $hb->pack_start (my $logbtn = Gtk2::Button->new ("add log"), 1, 1, 0); |
|
|
607 | $hb->pack_start (my $closebtn = Gtk2::Button->new ("close"), 1, 1, 0); |
|
|
608 | |
|
|
609 | my $buf = $txt->get_buffer (); |
|
|
610 | $buf->set_text ($self->{map}{map}{info}{msg}); |
|
|
611 | |
|
|
612 | $svbtn->signal_connect (clicked => sub { |
|
|
613 | my $buf = $txt->get_buffer (); |
|
|
614 | my $txt = $buf->get_text ($buf->get_start_iter, $buf->get_end_iter, 0); |
|
|
615 | $self->{map}{map}{info}{msg} = $txt; |
|
|
616 | }); |
|
|
617 | |
|
|
618 | $logbtn->signal_connect (clicked => sub { |
|
|
619 | my $buf = $txt->get_buffer (); |
|
|
620 | $buf->insert ($buf->get_start_iter, "- " . strftime ("%F %T %Z", localtime (time)) . " by " . ($main::CFG->{username} || $ENV{USER}) . ":\n"); |
|
|
621 | $txt->set_buffer ($buf); |
|
|
622 | }); |
|
|
623 | |
|
|
624 | $closebtn->signal_connect (clicked => sub { |
|
|
625 | $w->destroy; |
|
|
626 | }); |
|
|
627 | |
|
|
628 | ::set_pos_and_size ($w, $main::CFG->{map_info}, 400, 400, 220, 20); |
|
|
629 | $w->signal_connect (destroy => sub { |
|
|
630 | delete $self->{map_info}; |
|
|
631 | }); |
|
|
632 | $w->show_all; |
|
|
633 | } |
|
|
634 | |
562 | sub open_map_prop { |
635 | sub open_map_prop { |
563 | my ($self) = @_; |
636 | my ($self) = @_; |
564 | |
637 | |
565 | return if $self->{map_properties}; |
638 | return if $self->{map_properties}; |
566 | |
639 | |
… | |
… | |
569 | $w->init ( |
642 | $w->init ( |
570 | dialog_default_size => [500, 500, 220, 20], |
643 | dialog_default_size => [500, 500, 220, 20], |
571 | layout_name => 'map_prop_win', |
644 | layout_name => 'map_prop_win', |
572 | title => 'map properties', |
645 | title => 'map properties', |
573 | ref_hash => $self->{map}{map}{info}, |
646 | ref_hash => $self->{map}{map}{info}, |
|
|
647 | close_on_save => 1, |
574 | dialog => [ |
648 | dialog => [ |
575 | [qw/name Name string/], |
649 | [qw/name Name string/], |
576 | [qw/region Region string/], |
650 | [qw/region Region string/], |
577 | [qw/enter_x Enter-x string/], |
651 | [qw/enter_x Enter-x string/], |
578 | [qw/enter_y Enter-y string/], |
652 | [qw/enter_y Enter-y string/], |
… | |
… | |
594 | # [qw/msg Text text/], |
668 | # [qw/msg Text text/], |
595 | # [qw/maplore Maplore text/], |
669 | # [qw/maplore Maplore text/], |
596 | [qw/outdoor Outdoor check/], |
670 | [qw/outdoor Outdoor check/], |
597 | [qw/unique Unique check/], |
671 | [qw/unique Unique check/], |
598 | [qw/fixed_resettime Fixed-resettime check/], |
672 | [qw/fixed_resettime Fixed-resettime check/], |
|
|
673 | [per_player => 'Per player' => 'check'], |
|
|
674 | [per_party => 'Per party' => 'check'], |
|
|
675 | [no_reset => 'No reset' => 'check'], |
|
|
676 | [music => 'Map Music' => 'string'], |
599 | [undef, qw/x sep/], |
677 | [undef, qw/x sep/], |
600 | [qw/tile_path_1 Northpath string/], |
678 | [qw/tile_path_1 Northpath string/], |
601 | [qw/tile_path_2 Eastpath string/], |
679 | [qw/tile_path_2 Eastpath string/], |
602 | [qw/tile_path_3 Southpath string/], |
680 | [qw/tile_path_3 Southpath string/], |
603 | [qw/tile_path_4 Westpath string/], |
681 | [qw/tile_path_4 Westpath string/], |