ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MapEditor.pm
Revision: 1.15
Committed: Sun Mar 12 12:18:55 2006 UTC (18 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.14: +6 -3 lines
Log Message:
Implemented first parts of the new attribute editor.

File Contents

# Content
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 use Crossfire::Map;
15 use Crossfire::MapWidget;
16
17 use GCE::AttrEdit;
18
19 use Glib::Object::Subclass
20 Gtk2::Window;
21
22 use strict;
23
24 sub build_menu {
25 my ($self) = @_;
26
27 my $menu_tree = [
28 _File => {
29 item_type => '<Branch>',
30 children => [
31 "_Save" => {
32 callback => sub { $self->save_map },
33 accelerator => '<ctrl>S'
34 },
35 "Save As" => {
36 callback => sub { $self->save_map_as },
37 },
38 "Close" => {
39 callback => sub { $self->delete; 1 },
40 },
41 ]
42 },
43 _Edit => {
44 item_type => '<Branch>',
45 children => [
46 "_Undo" => {
47 callback => sub { $self->undo },
48 accelerator => "<ctrl>Z"
49 },
50 "_Redo" => {
51 callback => sub { $self->redo },
52 accelerator => "<ctrl>Y"
53 },
54
55 ]
56 },
57
58 ];
59
60 my $men =
61 Gtk2::SimpleMenu->new (
62 menu_tree => $menu_tree,
63 default_callback => \&default_cb,
64 );
65
66 $self->add_accel_group ($men->{accel_group});
67
68 return $men->{widget};
69 }
70
71 sub INIT_INSTANCE {
72 my ($self) = @_;
73
74 $self->set_title ('gce - map editor');
75 $self->add (my $vb = Gtk2::VBox->new);
76
77 $self->signal_connect (delete_event => sub { $self->delete });
78
79 $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0);
80
81 $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0);
82
83 $map->signal_connect (button_press_event => sub {
84 my ($map, $event) = @_;
85
86 my ($x, $y) = $map->coord ($event->x, $event->y);
87 my $as = $map->get ($x, $y);
88
89 my $btn = $event->button;
90
91 if ((not $self->{draw_mode})
92 and $btn != 2
93 and my $ea = $::MAINWIN->{sel_editaction}) {
94
95 $ea->begin ($map, $x, $y, $btn)
96 if $x >= 0 and $y >= 0 and $x < $map->{map}{width} and $y < $map->{map}{height};
97
98 $self->{draw_mode} = [$ea, $x, $y, $btn];
99
100 $ea->want_cursor
101 or $map->disable_tooltip;
102
103 if ($ea->special_arrow) {
104
105 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($ea->special_arrow));
106 #'GDK_QUESTION_ARROW'));
107 }
108
109 return 1;
110 }
111
112 0
113 });
114
115 $map->signal_connect_after (motion_notify_event => sub {
116 my ($map, $event) = @_;
117
118 $self->{draw_mode}
119 or return;
120
121 my ($X, $Y) = @{$self->{draw_mode}}[1,2];
122 my ($x, $y) = $map->coord ($map->get_pointer);
123
124 while ($x != $X || $y != $Y) {
125
126 $X++ if $X < $x;
127 $X-- if $X > $x;
128 $Y++ if $Y < $y;
129 $Y-- if $Y > $y;
130
131 $self->{draw_mode}[0]->edit ($map, $X, $Y, $self->{draw_mode}[3])
132 if $X >= 0 and $Y >= 0 and $X < $map->{map}{width} and $Y < $map->{map}{height};
133 }
134
135 @{$self->{draw_mode}}[1,2] = ($X, $Y);
136
137 1
138 });
139
140 $map->signal_connect (button_release_event => sub {
141 my ($map, $event) = @_;
142
143 if ($self->{draw_mode}
144 and my $ea = $self->{draw_mode}[0]
145 and $self->{draw_mode}[3] == $event->button) {
146
147 my ($x, $y) = $map->coord ($map->get_pointer);
148
149 $ea->end ($map, $x, $y, $event->button);
150
151 if ($ea->special_arrow) {
152
153 # XXX: Get the original cursor and insert it here
154 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
155 }
156
157 delete $self->{draw_mode};
158
159 $ea->want_cursor
160 or $map->enable_tooltip;
161
162 return 1;
163 }
164
165 0
166 });
167 }
168
169 sub undo {
170 my ($self) = @_;
171
172 my $map = $self->{map}; # the Crossfire::MapWidget
173
174 $map->{undo_stack_pos}
175 or return;
176
177 $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]);
178 }
179
180 sub redo {
181 my ($self) = @_;
182
183 my $map = $self->{map}; # the Crossfire::MapWidget
184
185 $map->{undo_stack}
186 and $map->{undo_stack_pos} < @{$map->{undo_stack}}
187 or return;
188
189 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]);
190 }
191
192 sub delete_arch {
193 my ($self, $x, $y) = @_;
194
195 defined $self->{map}
196 or return 0;
197
198 my $as = $self->{map}->get ($x, $y);
199 pop @$as;
200 $self->{map}->set ($x, $y, $as);
201 }
202
203 sub place_pick {
204 my ($self, $x, $y) = @_;
205
206 my $pick = $::MAINWIN->get_pick;
207 my $as = $self->{map}->get ($x, $y);
208
209 my $arch = { _name => $pick->{_name} };
210
211 push @$as, $arch
212 unless @$as && $as->[-1]->{_name} eq $arch->{_name};
213
214 $self->{map}->set ($x, $y, $as);
215 }
216
217 sub delete {
218 my ($self) = @_;
219
220 # check and modla dialog if "dirty"
221
222 $self->destroy;
223 }
224
225 sub open_map {
226 my ($self, $path) = @_;
227
228 $self->{path} = $path;
229 $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path);
230 require Data::Dumper;
231 }
232
233 sub save_map {
234 my ($self) = @_;
235
236 $self->{map}{map}->write_file ($self->{path});
237 }
238
239 sub save_map_as {
240 my ($self) = @_;
241 warn "save_map_as nyi\n";
242 }
243
244 =head1 AUTHOR
245
246 Marc Lehmann <schmorp@schmorp.de>
247 http://home.schmorp.de/
248
249 Robin Redeker <elmex@ta-sa.org>
250 http://www.ta-sa.org/
251
252 =cut
253 1;
254