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.17 by elmex, Sun Mar 12 14:39:19 2006 UTC vs.
Revision 1.25 by elmex, Thu Mar 16 23:58:10 2006 UTC

13use Crossfire; 13use Crossfire;
14use Crossfire::Map; 14use Crossfire::Map;
15use Crossfire::MapWidget; 15use Crossfire::MapWidget;
16 16
17use GCE::AttrEdit; 17use GCE::AttrEdit;
18use GCE::Util;
18 19
19use Glib::Object::Subclass 20use Glib::Object::Subclass
20 Gtk2::Window; 21 Gtk2::Window;
21 22
22use strict; 23use strict;
68 Gtk2::SimpleMenu->new ( 69 Gtk2::SimpleMenu->new (
69 menu_tree => $menu_tree, 70 menu_tree => $menu_tree,
70 default_callback => \&default_cb, 71 default_callback => \&default_cb,
71 ); 72 );
72 73
74 for (
75 [i => 'pick'],
76 [p => 'place'],
77 [e => 'erase'],
78 [s => 'select'],
79 [l => 'eval'],
80 [x => 'connectexit'],
81 [f => 'followexit']
82 )
83 {
84 my $tool = $_->[1];
85 $men->{accel_group}->connect ($Gtk2::Gdk::Keysyms{$_->[0]}, [], 'visible',
86 sub { $::MAINWIN->set_edit_tool ($tool) });
87 }
88
73 $self->add_accel_group ($men->{accel_group}); 89 $self->add_accel_group ($men->{accel_group});
74 90
75 return $men->{widget}; 91 return $men->{widget};
92}
93
94sub ea {
95 my ($self) = @_;
96 $self->{ea_alt} || $::MAINWIN->{sel_editaction};
76} 97}
77 98
78sub INIT_INSTANCE { 99sub INIT_INSTANCE {
79 my ($self) = @_; 100 my ($self) = @_;
80 101
81 $self->set_title ('gce - map editor'); 102 $self->set_title ('gce - map editor');
82 $self->add (my $vb = Gtk2::VBox->new); 103 $self->add (my $vb = Gtk2::VBox->new);
83 104
84 $self->signal_connect (delete_event => sub { $self->delete }); 105 $self->signal_connect (delete_event => sub { $self->delete; 1 });
85 106
86 $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0); 107 $vb->pack_start (my $menu = $self->build_menu, 0, 1, 0);
87 108
88 $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0); 109 $vb->pack_start (my $map = $self->{map} = Crossfire::MapWidget->new, 1, 1, 0);
89 110
111 $self->signal_connect (focus_in_event => sub {
112 my $ea = $::MAINWIN->{sel_editaction};
113 if ($ea->special_arrow) {
114 $self->{map}->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($ea->special_arrow));
115 } else {
116 $self->{map}->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
117 }
118 delete $self->{ea_alt};
119 });
120
121 $map->signal_connect (key_press_event => sub {
122 my ($map, $event) = @_;
123
124 my $kv = $event->keyval;
125
126 my ($x, $y) = $map->coord ($map->get_pointer);
127 for ([Control_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{erase} }],
128 [Alt_L => sub { $self->{ea_alt} = $::MAINWIN->{edit_collection}{pick} }],
129 [c => sub { $::MAINWIN->{edit_collection}{select}->copy }],
130 [v => sub { $::MAINWIN->{edit_collection}{select}->paste ($x, $y) }],
131 [n => sub { $::MAINWIN->{edit_collection}{select}->invoke }],
132 )
133 {
134 if ($kv == $Gtk2::Gdk::Keysyms{$_->[0]}) {
135 $_->[1]->();
136 }
137 }
138
139 if ($self->ea->special_arrow) {
140 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow));
141 }
142 1;
143 });
144 $map->signal_connect (key_release_event => sub {
145 my ($map, $event) = @_;
146
147 if ($event->keyval == $Gtk2::Gdk::Keysyms{Control_L}
148 or $event->keyval == $Gtk2::Gdk::Keysyms{Alt_L})
149 {
150 delete $self->{ea_alt};
151 }
152
153 if ($self->ea->special_arrow) {
154 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($self->ea->special_arrow));
155 } else {
156 # XXX: Get the original cursor and insert it here
157 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
158 }
159 1;
160 });
90 $map->signal_connect (button_press_event => sub { 161 $map->signal_connect (button_press_event => sub {
91 my ($map, $event) = @_; 162 my ($map, $event) = @_;
92 163
93 my ($x, $y) = $map->coord ($event->x, $event->y); 164 my ($x, $y) = $map->coord ($event->x, $event->y);
94 my $as = $map->get ($x, $y); 165 my $as = $map->get ($x, $y);
95 166
96 my $btn = $event->button; 167 if ((not $self->{draw_mode}) and $event->button != 2) {
97 168
98 if ((not $self->{draw_mode}) 169 my $ea = $self->ea;
99 and $btn != 2
100 and my $ea = $::MAINWIN->{sel_editaction}) {
101 170
102 $ea->begin ($map, $x, $y, $btn) 171 $ea->begin ($map, $x, $y, $self)
103 if $x >= 0 and $y >= 0 and $x < $map->{map}{width} and $y < $map->{map}{height}; 172 if $x >= 0 and $y >= 0 and $x < $map->{map}{width} and $y < $map->{map}{height};
104 173
105 $self->{draw_mode} = [$ea, $x, $y, $btn]; 174 $self->{draw_mode} = [$x, $y];
106 175
107 $ea->want_cursor 176 $ea->want_cursor
108 or $map->disable_tooltip; 177 or $map->disable_tooltip;
109 178
110 if ($ea->special_arrow) {
111
112 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ($ea->special_arrow));
113 #'GDK_QUESTION_ARROW'));
114 }
115
116 return 1; 179 return 1;
117 } 180 }
118
119 0 181 0
120 }); 182 });
121 183
122 $map->signal_connect_after (motion_notify_event => sub { 184 $map->signal_connect_after (motion_notify_event => sub {
123 my ($map, $event) = @_; 185 my ($map, $event) = @_;
124 186
125 $self->{draw_mode} 187 $self->{draw_mode}
126 or return; 188 or return;
127 189
190 my $ea = $self->ea;
191
128 my ($X, $Y) = @{$self->{draw_mode}}[1,2]; 192 my ($X, $Y) = @{$self->{draw_mode}}[0,1];
129 my ($x, $y) = $map->coord ($map->get_pointer); 193 my ($x, $y) = $map->coord ($map->get_pointer);
130 194
131 while ($x != $X || $y != $Y) { 195 while ($x != $X || $y != $Y) {
132 196
133 $X++ if $X < $x; 197 $X++ if $X < $x;
134 $X-- if $X > $x; 198 $X-- if $X > $x;
135 $Y++ if $Y < $y; 199 $Y++ if $Y < $y;
136 $Y-- if $Y > $y; 200 $Y-- if $Y > $y;
137 201
138 $self->{draw_mode}[0]->edit ($map, $X, $Y, $self->{draw_mode}[3]) 202 $ea->edit ($map, $X, $Y, $self)
139 if $X >= 0 and $Y >= 0 and $X < $map->{map}{width} and $Y < $map->{map}{height}; 203 if $X >= 0 and $Y >= 0 and $X < $map->{map}{width} and $Y < $map->{map}{height};
140 } 204 }
141 205
142 @{$self->{draw_mode}}[1,2] = ($X, $Y); 206 @{$self->{draw_mode}}[0,1] = ($X, $Y);
143 207
144 1 208 1
145 }); 209 });
146 210
147 $map->signal_connect (button_release_event => sub { 211 $map->signal_connect (button_release_event => sub {
148 my ($map, $event) = @_; 212 my ($map, $event) = @_;
149 213
150 if ($self->{draw_mode} 214 if ($self->{draw_mode}) {
151 and my $ea = $self->{draw_mode}[0]
152 and $self->{draw_mode}[3] == $event->button) {
153
154 my ($x, $y) = $map->coord ($map->get_pointer); 215 my ($x, $y) = $map->coord ($map->get_pointer);
155 216
217 my $ea = $self->ea;
156 $ea->end ($map, $x, $y, $event->button); 218 $ea->end ($map, $x, $y, $self);
157
158 if ($ea->special_arrow) {
159
160 # XXX: Get the original cursor and insert it here
161 $map->{window}->set_cursor (Gtk2::Gdk::Cursor->new ('GDK_LEFT_PTR'));
162 }
163 219
164 delete $self->{draw_mode}; 220 delete $self->{draw_mode};
165 221
166 $ea->want_cursor 222 $ea->want_cursor
167 or $map->enable_tooltip; 223 or $map->enable_tooltip;
195 or return; 251 or return;
196 252
197 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]); 253 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]);
198} 254}
199 255
200sub delete_arch {
201 my ($self, $x, $y) = @_;
202
203 defined $self->{map}
204 or return 0;
205
206 my $as = $self->{map}->get ($x, $y);
207 pop @$as;
208 $self->{map}->set ($x, $y, $as);
209}
210
211sub place_pick {
212 my ($self, $x, $y) = @_;
213
214 my $pick = $::MAINWIN->get_pick;
215 my $as = $self->{map}->get ($x, $y);
216
217 my $arch = { _name => $pick->{_name} };
218
219 push @$as, $arch
220 unless @$as && $as->[-1]->{_name} eq $arch->{_name};
221
222 $self->{map}->set ($x, $y, $as);
223}
224
225sub delete { 256sub delete {
226 my ($self) = @_; 257 my ($self) = @_;
227 258
228 # check and modla dialog if "dirty" 259 # check and modla dialog if "dirty"
260
261 if ($self->{path}) {
262 # XXX: This should be in a delete event handler in the MainWindow.pm... but it doesnt work
263 delete $::MAINWIN->{loaded_maps}->{$self->{path}};
264 }
229 265
230 $self->destroy; 266 $self->destroy;
231} 267}
232 268
233sub open_map { 269sub open_map {
234 my ($self, $path) = @_; 270 my ($self, $path) = @_;
235 271
272 if (ref $path) {
273 $self->{map}->set_map ($path);
274
275 } else {
236 $self->{path} = $path; 276 $self->{path} = $path;
237# print "OPENMAP $path\n"; 277# print "OPENMAP $path\n";
238 $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path); 278 $self->{map}->set_map (my $m = new_from_file Crossfire::Map $path);
239 require Data::Dumper; 279 require Data::Dumper;
240 print "FOO:" .Data::Dumper::Dumper ($m) . "\n"; 280# print "FOO:" .Data::Dumper::Dumper ($m) . "\n";
281 }
241} 282}
242 283
243sub save_map { 284sub save_map {
244 my ($self) = @_; 285 my ($self) = @_;
245 286
287 if ($self->{path}) {
246 $self->{map}{map}->write_file ($self->{path}); 288 $self->{map}{map}->write_file ($self->{path});
289 quick_msg ($self, "saved to $self->{path}");
290 } else {
291 $self->save_map_as;
292 }
247} 293}
248 294
249sub save_map_as { 295sub save_map_as {
250 my ($self) = @_; 296 my ($self) = @_;
251 warn "save_map_as nyi\n"; 297
298 my $fc = $::MAINWIN->new_filechooser ('gce - save map', 1, $self->{path});
299
300 if ('ok' eq $fc->run) {
301
302 $::MAINWIN->{fc_last_folder} = $fc->get_current_folder;
303 $::MAINWIN->{fc_last_folders}->{$self->{fc_last_folder}}++;
304
305 $self->{map}{map}->write_file ($self->{path} = $fc->get_filename);
306 quick_msg ($self, "saved to $self->{path}");
307 }
308
309 $fc->destroy;
252} 310}
253 311
254sub _add_prop_entry { 312sub _add_prop_entry {
255 my ($self, $table, $idx, $key, $desc, $type, $changecb) = @_; 313 my ($self, $table, $idx, $key, $desc, $type, $changecb) = @_;
256
257 314
258 my $edwid; 315 my $edwid;
259 316
260 if ($type eq 'string') { 317 if ($type eq 'string') {
261 $table->attach_defaults (my $lbl = Gtk2::Label->new ($desc), 0, 1, $idx, $idx + 1); 318 $table->attach_defaults (my $lbl = Gtk2::Label->new ($desc), 0, 1, $idx, $idx + 1);
262 $edwid = Gtk2::Entry->new; 319 $edwid = Gtk2::Entry->new;
263 $edwid->set_text ($self->{map}{map}{info}{$key}); 320 $edwid->set_text ($self->{map}{map}{info}{$key});
264 $edwid->signal_connect (changed => sub { 321 $edwid->signal_connect (changed => sub {
265 $self->{map}{map}{info}{$key} = $_[0]->get_text; 322 $self->{map}{map}{info}{$key} = $_[0]->get_text;
266 if ($changecb) { 323 if ($changecb) {
267 print "CHANGECB " . $_[0]->get_text . "\n";
268 $changecb->($_[0]->get_text); 324 $changecb->($_[0]->get_text);
269 } 325 }
270 }); 326 });
271 $table->attach_defaults ($edwid, 1, 2, $idx, $idx + 1); 327 $table->attach_defaults ($edwid, 1, 2, $idx, $idx + 1);
272 328
299 [qw/width Width string/], 355 [qw/width Width string/],
300 [qw/height Height string/], 356 [qw/height Height string/],
301 [qw/save Save button/, 357 [qw/save Save button/,
302 sub { 358 sub {
303 $self->{map}{map}->resize ($self->{map}{map}{info}{width}, $self->{map}{map}{info}{height}); 359 $self->{map}{map}->resize ($self->{map}{map}{info}{width}, $self->{map}{map}{info}{height});
304 $self->{map}->invalidate_all 360 $self->{map}->invalidate_all;
361 $w->destroy;
305 } 362 }
306 ], 363 ],
307 ) 364 )
308 { 365 {
309 $self->_add_prop_entry ($t, $i++, @$_); 366 $self->_add_prop_entry ($t, $i++, @$_);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines