… | |
… | |
14 | use Crossfire::MapWidget; |
14 | use Crossfire::MapWidget; |
15 | |
15 | |
16 | use GCE::AttrEdit; |
16 | use GCE::AttrEdit; |
17 | use GCE::MapEditor; |
17 | use GCE::MapEditor; |
18 | use GCE::StackView; |
18 | use GCE::StackView; |
|
|
19 | use GCE::EditAction; |
|
|
20 | use GCE::PickWindow; |
19 | |
21 | |
20 | use GCE::AttrTypemap; |
22 | use GCE::AttrTypemap; |
21 | |
23 | |
22 | use Glib::Object::Subclass |
24 | use Glib::Object::Subclass |
23 | Gtk2::Window; |
25 | Gtk2::Window; |
24 | |
26 | |
25 | use strict; |
27 | use strict; |
26 | |
28 | |
27 | our $MAINWIN; |
29 | our $MAINWIN; |
28 | |
30 | |
|
|
31 | sub save_layout { |
|
|
32 | my ($self) = @_; |
|
|
33 | |
|
|
34 | $main::CFG->{attr_edit_on} = exists $self->{attr_edit} ? 1 : 0; |
|
|
35 | $main::CFG->{stack_view_on} = exists $self->{sv} ? 1 : 0; |
|
|
36 | $main::CFG->{picker_on} = exists $self->{last_pick_window} ? 1 : 0; |
|
|
37 | $main::CFG->{main_window} = main::get_pos_and_size ($self); |
|
|
38 | $main::CFG->{map_window} = main::get_pos_and_size ($self->{last_map_window}) if $self->{last_map_window}; |
|
|
39 | $main::CFG->{stack_view} = main::get_pos_and_size ($self->{sv_win}) if $self->{sv_win}; |
|
|
40 | $main::CFG->{attr_view} = main::get_pos_and_size ($self->{attr_edit_win}) if $self->{attr_edit_win}; |
|
|
41 | |
|
|
42 | $main::CFG->{open_pickers} = []; |
|
|
43 | |
|
|
44 | for (@{$self->{open_pick_windows}}) { |
|
|
45 | |
|
|
46 | next unless defined $_; |
|
|
47 | |
|
|
48 | push @{$main::CFG->{open_pickers}}, { |
|
|
49 | p_and_s => main::get_pos_and_size ($_), |
|
|
50 | selection => $_->{last_selection} |
|
|
51 | }; |
|
|
52 | } |
|
|
53 | |
|
|
54 | main::write_cfg ($main::VARDIR . '/config'); |
|
|
55 | } |
|
|
56 | |
|
|
57 | sub load_layout { |
|
|
58 | my ($self) = @_; |
|
|
59 | |
|
|
60 | $main::CFG->{attr_edit_on} |
|
|
61 | and $self->show_attr_editor; |
|
|
62 | |
|
|
63 | $main::CFG->{stack_view_on} |
|
|
64 | and $self->show_stack_view; |
|
|
65 | |
|
|
66 | for (@{$main::CFG->{open_pickers}}) { |
|
|
67 | $self->open_pick_window ($_); |
|
|
68 | } |
|
|
69 | } |
|
|
70 | |
|
|
71 | sub open_map_editor { |
|
|
72 | my ($self, $mapfile) = @_; |
|
|
73 | |
|
|
74 | # XXX: last_map_window is a dirty trick to get the position and size |
|
|
75 | # for save layout |
|
|
76 | |
|
|
77 | my $w = $self->{last_map_window} = GCE::MapEditor->new; |
|
|
78 | $self->{mapedit} = $w->{mapedit}; |
|
|
79 | $w->open_map ($mapfile); |
|
|
80 | |
|
|
81 | main::set_pos_and_size ($w, $main::CFG->{map_window}); |
|
|
82 | |
|
|
83 | $w->show_all; |
|
|
84 | # my $w = $self->{last_map_window} = Gtk2::Window->new ('toplevel'); |
|
|
85 | # $w->set_title ('gce - map editor'); |
|
|
86 | # $w->add (my $mapedit = $self->{mapedit} = new GCE::MapEditor); |
|
|
87 | # $mapedit->open_map ($mapfile); |
|
|
88 | # |
|
|
89 | # |
|
|
90 | # $w->show_all; |
|
|
91 | } |
|
|
92 | |
29 | sub test_stack_view { |
93 | sub show_stack_view { |
30 | my ($self) = @_; |
94 | my ($self) = @_; |
31 | |
95 | |
32 | return if defined $self->{sv}; |
96 | return if defined $self->{sv}; |
33 | |
97 | |
34 | my $w = Gtk2::Window->new ('toplevel'); |
98 | my $w = $self->{sv_win} = Gtk2::Window->new ('toplevel'); |
35 | $w->set_title ('gce - stack view'); |
99 | $w->set_title ('gce - stack view'); |
36 | $w->signal_connect ('delete-event' => sub { $self->{sv} = undef; }); |
100 | $w->signal_connect ('delete-event' => sub { delete $self->{sv}; 0 }); |
37 | $w->add ($self->{sv} = GCE::StackView->new); |
101 | $w->add ($self->{sv} = GCE::StackView->new); |
|
|
102 | |
|
|
103 | main::set_pos_and_size ($w, $main::CFG->{stack_view}); |
|
|
104 | |
38 | $w->show_all; |
105 | $w->show_all; |
39 | } |
106 | } |
40 | |
107 | |
41 | sub show_attr_editor { |
108 | sub show_attr_editor { |
42 | my ($self) = @_; |
109 | my ($self) = @_; |
|
|
110 | |
|
|
111 | return if $self->{attr_edit}; |
43 | |
112 | |
44 | my $w = $self->{attr_edit_win} = Gtk2::Window->new; |
113 | my $w = $self->{attr_edit_win} = Gtk2::Window->new; |
45 | $w->set_title ("gce - edit attrs"); |
114 | $w->set_title ("gce - edit attrs"); |
46 | $w->add ($self->{attr_edit} = GCE::AttrEdit->new); |
115 | $w->add ($self->{attr_edit} = GCE::AttrEdit->new); |
47 | $w->signal_connect ('delete-event' => sub { delete $self->{attr_edit}; 0 }); |
116 | $w->signal_connect ('delete-event' => sub { delete $self->{attr_edit}; 0 }); |
|
|
117 | |
|
|
118 | main::set_pos_and_size ($w, $main::CFG->{attr_view}); |
|
|
119 | |
48 | $w->show_all; |
120 | $w->show_all; |
49 | } |
121 | } |
50 | |
122 | |
51 | sub update_attr_editor { |
123 | sub update_attr_editor { |
52 | my ($self, $arch, $ro) = @_; |
124 | my ($self, $arch, $cb) = @_; |
53 | |
125 | |
54 | return unless $self->{attr_edit}; |
126 | return unless $self->{attr_edit}; |
55 | |
127 | |
56 | $self->{attr_edit}->set_arch ($arch, $ro); |
128 | $self->{attr_edit}->set_arch ($arch, $cb); |
57 | $self->{attr_edit_win}->set_title ("gce - edit $arch->{_name}"); |
129 | $self->{attr_edit_win}->set_title ("gce - edit $arch->{_name}"); |
58 | } |
130 | } |
59 | |
131 | |
60 | sub update_stack_view { |
132 | sub update_stack_view { |
61 | my ($self, $mapedit, $stack, $x, $y) = @_; |
133 | my ($self, $mapedit, $x, $y) = @_; |
62 | |
134 | |
63 | return unless $self->{sv}; |
135 | return unless $self->{sv}; |
64 | |
136 | |
65 | $self->{sv}->set_stack ($mapedit, $stack, $x, $y); |
137 | $self->{sv}->set_stack ($mapedit, $x, $y); |
66 | } |
|
|
67 | |
|
|
68 | #XXX: Soon we want to handle multiple maps! |
|
|
69 | #XXX: Refactor this to MapEditor?? |
|
|
70 | sub change_map_tile { |
|
|
71 | my ($self, $mapedit, $x, $y, $newstack, $oldstack) = @_; |
|
|
72 | |
|
|
73 | $mapedit->{map}->set ($x, $y, $newstack); |
|
|
74 | } |
138 | } |
75 | |
139 | |
76 | sub open_pick_window { |
140 | sub open_pick_window { |
77 | my ($self) = @_; |
141 | my ($self, $layout) = @_; |
78 | |
142 | |
|
|
143 | # XXX: Yes, also fix this, save _every_ pick window and their posistions and their |
|
|
144 | # selection |
79 | my $p = GCE::PickWindow->new ( |
145 | my $p = GCE::PickWindow->new (); |
80 | set_sel_cb => sub { |
|
|
81 | |
146 | |
82 | $self->{mapedit}->update_pick ($_[0]) |
147 | push @{$self->{open_pick_windows}}, $p; |
83 | }, |
|
|
84 | arch_edit_cb => sub { |
|
|
85 | |
148 | |
86 | $self->update_attr_editor ($_[0], 1) |
149 | my $idx = (@{$self->{open_pick_windows}}) - 1; |
87 | } |
150 | |
|
|
151 | $p->signal_connect ('delete-event' => sub { |
|
|
152 | $self->{open_pick_windows}->[$idx] = undef; |
88 | ); |
153 | }); |
89 | $p->init; |
154 | |
|
|
155 | if ($layout) { |
|
|
156 | main::set_pos_and_size ($p, $layout->{p_and_s}); |
|
|
157 | } |
|
|
158 | |
|
|
159 | $p->show_all; |
|
|
160 | |
|
|
161 | $p->set_selection ($layout->{selection}); |
90 | } |
162 | } |
91 | |
163 | |
92 | sub build_menu { |
164 | sub build_menu { |
93 | my ($self) = @_; |
165 | my ($self) = @_; |
94 | |
166 | |
… | |
… | |
101 | accelerator => '<ctrl>N' |
173 | accelerator => '<ctrl>N' |
102 | }, |
174 | }, |
103 | _Open => { |
175 | _Open => { |
104 | callback => sub { $self->open_cb }, |
176 | callback => sub { $self->open_cb }, |
105 | accelerator => '<ctrl>O' |
177 | accelerator => '<ctrl>O' |
|
|
178 | }, |
|
|
179 | "_Save Layout" => { |
|
|
180 | callback => sub { $self->save_layout }, |
|
|
181 | accelerator => '<ctrl>L' |
106 | }, |
182 | }, |
107 | _Quit => { |
183 | _Quit => { |
108 | callback => sub { Gtk2->main_quit }, |
184 | callback => sub { Gtk2->main_quit }, |
109 | accelerator => '<ctrl>Q' |
185 | accelerator => '<ctrl>Q' |
110 | } |
186 | } |
111 | ] |
187 | ] |
112 | }, |
188 | }, |
113 | _Edit => { |
189 | _Edit => { |
114 | item_type => '<Branch>', |
190 | item_type => '<Branch>', |
115 | children => [ |
191 | children => [ |
116 | _Fill => { |
192 | "_Attr Editor" => { |
117 | callback => sub { die "NO IMPL" }, |
193 | callback => sub { $self->show_attr_editor }, |
118 | accelerator => "<ctrl>F" |
194 | accelerator => "<ctrl>A" |
119 | }, |
195 | }, |
120 | "Clear _Top" => { |
196 | "_Picker" => { |
121 | callback => sub { die "NO IMPL" }, |
197 | callback => sub { $self->open_pick_window }, |
122 | accelerator => "<ctrl>T" |
198 | accelerator => "<ctrl>P" |
123 | }, |
199 | }, |
124 | "_Clear All" => { |
200 | "_Stack View" => { |
125 | callback => sub { die "NO IMPL" }, |
201 | callback => sub { $self->show_stack_view }, |
126 | accelerator => "<ctrl>X" |
202 | accelerator => "<ctrl>V" |
|
|
203 | }, |
|
|
204 | |
127 | }, |
205 | ] |
|
|
206 | }, |
|
|
207 | _View => { |
|
|
208 | item_type => '<Branch>', |
|
|
209 | children => [ |
128 | "Open _Attr Editor" => { |
210 | "Open _Attr Editor" => { |
129 | callback => sub { $self->show_attr_editor }, |
211 | callback => sub { $self->show_attr_editor }, |
130 | accelerator => "<ctrl>A" |
212 | accelerator => "<ctrl>A" |
131 | }, |
213 | }, |
132 | "Open _Picker" => { |
214 | "Open _Picker" => { |
133 | callback => sub { $self->open_pick_window }, |
215 | callback => sub { $self->open_pick_window }, |
134 | accelerator => "<ctrl>P" |
216 | accelerator => "<ctrl>P" |
135 | }, |
217 | }, |
136 | "Open _Stack View" => { |
218 | "Open _Stack View" => { |
137 | callback => sub { $self->test_stack_view }, |
219 | callback => sub { $self->show_stack_view }, |
138 | accelerator => "<ctrl>V" |
220 | accelerator => "<ctrl>V" |
139 | }, |
221 | }, |
140 | |
222 | |
141 | ] |
223 | ] |
142 | } |
224 | } |
|
|
225 | |
143 | ]; |
226 | ]; |
144 | |
227 | |
145 | my $men = |
228 | my $men = |
146 | Gtk2::SimpleMenu->new ( |
229 | Gtk2::SimpleMenu->new ( |
147 | menu_tree => $menu_tree, |
230 | menu_tree => $menu_tree, |
… | |
… | |
151 | $self->add_accel_group ($men->{accel_group}); |
234 | $self->add_accel_group ($men->{accel_group}); |
152 | |
235 | |
153 | return $men->{widget}; |
236 | return $men->{widget}; |
154 | } |
237 | } |
155 | |
238 | |
|
|
239 | sub add_button { |
|
|
240 | my ($self, $table, $plcinfo, $lbl, $cb) = @_; |
|
|
241 | |
|
|
242 | my ($lx, $ly) = @{$plcinfo->{next}}; |
|
|
243 | |
|
|
244 | unless ($lx < $plcinfo->{width}) { |
|
|
245 | |
|
|
246 | $ly++; |
|
|
247 | $lx = 0; |
|
|
248 | } |
|
|
249 | |
|
|
250 | $ly < $plcinfo->{height} |
|
|
251 | or die "too many buttons, make table bigger!"; |
|
|
252 | |
|
|
253 | $table->attach_defaults (my $btn = Gtk2::Button->new_with_label ($lbl), $lx, $lx + 1, $ly, $ly + 1); |
|
|
254 | $btn->signal_connect (clicked => $cb); |
|
|
255 | |
|
|
256 | $plcinfo->{next} = [$lx + 1, $ly]; |
|
|
257 | } |
|
|
258 | |
|
|
259 | sub build_buttons { |
|
|
260 | my ($self) = @_; |
|
|
261 | |
|
|
262 | my $tbl = Gtk2::Table->new (2, 2); |
|
|
263 | my $plcinfo = { width => 1, height => 3, next => [0, 0] }; |
|
|
264 | |
|
|
265 | $self->{edit_collection}{pick} = GCE::EditAction::Pick->new; |
|
|
266 | $self->{edit_collection}{place} = GCE::EditAction::Place->new; |
|
|
267 | $self->{edit_collection}{erase} = GCE::EditAction::Erase->new; |
|
|
268 | |
|
|
269 | $self->add_button ($tbl, $plcinfo, "Pick", sub { |
|
|
270 | $self->{sel_editaction} = $self->{edit_collection}{pick}; |
|
|
271 | $self->{edit_tool}->set_text ("Pick"); |
|
|
272 | }); |
|
|
273 | $self->add_button ($tbl, $plcinfo, "Place", sub { |
|
|
274 | $self->{sel_editaction} = $self->{edit_collection}{place}; |
|
|
275 | $self->{edit_tool}->set_text ("Place"); |
|
|
276 | }); |
|
|
277 | $self->add_button ($tbl, $plcinfo, "Erase", sub { |
|
|
278 | $self->{sel_editaction} = $self->{edit_collection}{erase}; |
|
|
279 | $self->{edit_tool}->set_text ("Erase"); |
|
|
280 | }); |
|
|
281 | |
|
|
282 | return $tbl; |
|
|
283 | } |
156 | |
284 | |
157 | |
285 | |
158 | sub INIT_INSTANCE { |
286 | sub INIT_INSTANCE { |
159 | my ($self) = @_; |
287 | my ($self) = @_; |
160 | |
288 | |
… | |
… | |
162 | |
290 | |
163 | $self->set_title ("gce - main window"); |
291 | $self->set_title ("gce - main window"); |
164 | |
292 | |
165 | $self->add (my $vb = Gtk2::VBox->new); |
293 | $self->add (my $vb = Gtk2::VBox->new); |
166 | $vb->pack_start ($self->build_menu, 0, 1, 0); |
294 | $vb->pack_start ($self->build_menu, 0, 1, 0); |
167 | |
295 | $vb->pack_start (my $tbl = $self->build_buttons, 1, 1, 0); |
168 | $vb->pack_start (my $mapedit = $self->{mapedit} = new GCE::MapEditor, 1, 1, 0); |
296 | $vb->pack_start ($self->{edit_tool} = Gtk2::Label->new, 0, 1, 0); |
|
|
297 | $vb->pack_start ($self->{pick_view} = Gtk2::Label->new, 0, 1, 0); |
169 | |
298 | |
170 | # XXX:load $ARGV _cleanly_? |
299 | # XXX:load $ARGV _cleanly_? |
171 | $mapedit->open_map ($ARGV[0] || "$Crossfire::LIB/maps/dragonisland/advguild3"); |
300 | $self->open_map_editor ($ARGV[0] || "$Crossfire::LIB/maps/dragonisland/advguild3"); |
172 | |
301 | |
173 | $self->signal_connect ('delete-event' => sub { |
302 | $self->signal_connect ('delete-event' => sub { |
174 | Gtk2->main_quit; |
303 | Gtk2->main_quit; |
175 | }); |
304 | }); |
|
|
305 | |
|
|
306 | main::set_pos_and_size ($self, $main::CFG->{main_window}); |
176 | } |
307 | } |
177 | |
308 | |
178 | sub new_cb { |
309 | sub new_cb { |
179 | my ($self) = @_; |
310 | my ($self) = @_; |
180 | die "NOT IMPLEMENTED YET"; |
311 | die "NOT IMPLEMENTED YET"; |
… | |
… | |
194 | |
325 | |
195 | if ('ok' eq $fc->run) { |
326 | if ('ok' eq $fc->run) { |
196 | |
327 | |
197 | $self->{fc_last_folder} = $fc->get_current_folder; |
328 | $self->{fc_last_folder} = $fc->get_current_folder; |
198 | $self->{fc_last_folders}->{$self->{fc_last_folder}}++; |
329 | $self->{fc_last_folders}->{$self->{fc_last_folder}}++; |
|
|
330 | |
199 | $self->{mapedit}->open_map ($fc->get_filename); |
331 | $self->open_map_editor ($fc->get_filename); |
200 | } |
332 | } |
201 | |
333 | |
202 | $fc->destroy; |
334 | $fc->destroy; |
|
|
335 | } |
|
|
336 | |
|
|
337 | sub set_pick { |
|
|
338 | my ($self, $arch) = @_; |
|
|
339 | |
|
|
340 | $self->{pick_arch} = $arch; |
|
|
341 | $self->{pick_view}->set_text ($arch->{_name}); |
|
|
342 | } |
|
|
343 | |
|
|
344 | sub get_pick { |
|
|
345 | my ($self) = @_; |
|
|
346 | |
|
|
347 | # XXX: This is just to make sure that this function always returns something |
|
|
348 | return $self->{pick_arch} || { _name => 'platinacoin' }; |
203 | } |
349 | } |
204 | |
350 | |
205 | =head1 AUTHOR |
351 | =head1 AUTHOR |
206 | |
352 | |
207 | Marc Lehmann <schmorp@schmorp.de> |
353 | Marc Lehmann <schmorp@schmorp.de> |