ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MainWindow.pm
Revision: 1.20
Committed: Mon Feb 20 23:48:15 2006 UTC (18 years, 3 months ago) by root
Branch: MAIN
Changes since 1.19: +14 -4 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 package GCE::MainWindow;
2
3 =head1 NAME
4
5 GCE::MainWindow - the main window class for gce
6
7 =cut
8
9 use Gtk2;
10 use Gtk2::Gdk::Keysyms;
11 use Gtk2::SimpleMenu;
12
13 use Crossfire;
14 use Crossfire::MapWidget;
15
16 use GCE::AttrEdit;
17 use GCE::MapEditor;
18 use GCE::StackView;
19 use GCE::EditAction;
20 use GCE::PickWindow;
21
22 use GCE::AttrTypemap;
23
24 use Glib::Object::Subclass
25 Gtk2::Window;
26
27 use strict;
28
29 our $MAINWIN;
30
31 # XXX: make a recursive call from save_layout to all (interesting) sub-widgets
32 sub save_layout {
33 my ($self) = @_;
34
35 $main::CFG->{attr_edit_on} = exists $self->{attr_edit} ? 1 : 0;
36 $main::CFG->{stack_view_on} = exists $self->{sv} ? 1 : 0;
37 $main::CFG->{picker_on} = exists $self->{last_pick_window} ? 1 : 0;
38 $main::CFG->{main_window} = main::get_pos_and_size ($self);
39 $main::CFG->{map_window} = main::get_pos_and_size ($self->{last_map_window}) if $self->{last_map_window};
40 $main::CFG->{stack_view} = main::get_pos_and_size ($self->{sv_win}) if $self->{sv_win};
41 $main::CFG->{attr_view} = main::get_pos_and_size ($self->{attr_edit_win}) if $self->{attr_edit_win};
42
43 $main::CFG->{open_pickers} = [];
44
45 for (@{$self->{open_pick_windows}}) {
46
47 next unless defined $_;
48
49 push @{$main::CFG->{open_pickers}}, {
50 p_and_s => main::get_pos_and_size ($_),
51 selection => $_->{last_selection}
52 };
53 }
54
55 main::write_cfg ($main::VARDIR . '/config');
56 }
57
58 sub load_layout {
59 my ($self) = @_;
60
61 $main::CFG->{attr_edit_on}
62 and $self->show_attr_editor;
63
64 $main::CFG->{stack_view_on}
65 and $self->show_stack_view;
66
67 for (@{$main::CFG->{open_pickers}}) {
68 $self->open_pick_window ($_);
69 }
70 }
71
72 sub open_map_editor {
73 my ($self, $mapfile) = @_;
74
75 # XXX: last_map_window is a dirty trick to get the position and size
76 # for save layout
77
78 my $w = $self->{last_map_window} = GCE::MapEditor->new;
79 $self->{mapedit} = $w->{mapedit}; # this line can be ignored and will be deleted :)
80 $w->open_map ($mapfile);
81
82 main::set_pos_and_size ($w, $main::CFG->{map_window});
83
84 $w->show_all;
85 # my $w = $self->{last_map_window} = Gtk2::Window->new ('toplevel');
86 # $w->set_title ('gce - map editor');
87 # $w->add (my $mapedit = $self->{mapedit} = new GCE::MapEditor);
88 # $mapedit->open_map ($mapfile);
89 #
90 #
91 # $w->show_all;
92 }
93
94 sub show_stack_view {
95 my ($self) = @_;
96
97 return if defined $self->{sv};
98
99 my $w = $self->{sv_win} = Gtk2::Window->new ('toplevel');
100 $w->set_title ('gce - stack view');
101 $w->signal_connect ('delete-event' => sub { delete $self->{sv}; 0 });
102 $w->add ($self->{sv} = GCE::StackView->new);
103
104 main::set_pos_and_size ($w, $main::CFG->{stack_view});
105
106 $w->show_all;
107 }
108
109 sub show_attr_editor {
110 my ($self) = @_;
111
112 return if $self->{attr_edit};
113
114 my $w = $self->{attr_edit_win} = Gtk2::Window->new;
115 $w->set_title ("gce - edit attrs");
116 $w->add ($self->{attr_edit} = GCE::AttrEdit->new);
117 $w->signal_connect ('delete-event' => sub { delete $self->{attr_edit}; 0 });
118
119 main::set_pos_and_size ($w, $main::CFG->{attr_view});
120
121 $w->show_all;
122 }
123
124 sub update_attr_editor {
125 my ($self, $arch, $cb) = @_;
126
127 return unless $self->{attr_edit};
128
129 $self->{attr_edit}->set_arch ($arch, $cb);
130 $self->{attr_edit_win}->set_title ("gce - edit $arch->{_name}");
131 }
132
133 sub update_stack_view {
134 my ($self, $mapedit, $x, $y) = @_;
135
136 return unless $self->{sv};
137
138 $self->{sv}->set_stack ($mapedit, $x, $y);
139 }
140
141 sub open_pick_window {
142 my ($self, $layout) = @_;
143
144 # XXX: Yes, also fix this, save _every_ pick window and their posistions and their
145 # selection
146 my $p = GCE::PickWindow->new ();
147
148 push @{$self->{open_pick_windows}}, $p;
149
150 my $idx = (@{$self->{open_pick_windows}}) - 1;
151
152 $p->signal_connect ('delete-event' => sub {
153 $self->{open_pick_windows}->[$idx] = undef;
154 });
155
156 if ($layout) {
157 main::set_pos_and_size ($p, $layout->{p_and_s});
158 }
159
160 $p->show_all;
161
162 $p->set_selection ($layout->{selection});
163 }
164
165 sub undo {
166 my ($self) = @_;
167
168 # XXX: Move to GCE::MapEdior in a popup-menu or real menu
169 my $map = $self->{last_map_window}{mapedit}; # the Crossfire::MapWidget
170
171 warn $map;
172 warn "USI: $map->{undo_stack_pos} @{$map->{undo_stack} || []}\n";#d#
173 $map->{undo_stack_pos}
174 or return;
175
176 $map->change_swap ($map->{undo_stack}[--$map->{undo_stack_pos}]);
177 }
178
179 sub redo {
180 my ($self) = @_;
181
182 # XXX: Move to GCE::MapEdior in a popup-menu or real menu
183 my $map = $self->{last_map_window}{mapedit}; # the Crossfire::MapWidget
184
185 warn "RSI: $map->{undo_stack_pos} @{$map->{undo_stack}}\n";#d#
186
187 $map->{undo_stack_pos} < @{$map->{undo_stack}}
188 or return;
189
190 $map->change_swap ($map->{undo_stack}[$map->{undo_stack_pos}++]);
191 }
192
193 sub build_menu {
194 my ($self) = @_;
195
196 my $menu_tree = [
197 _File => {
198 item_type => '<Branch>',
199 children => [
200 _New => {
201 callback => sub { $self->new_cb },
202 accelerator => '<ctrl>N'
203 },
204 _Open => {
205 callback => sub { $self->open_cb },
206 accelerator => '<ctrl>O'
207 },
208 "_Save Layout" => {
209 callback => sub { $self->save_layout },
210 accelerator => '<ctrl>L'
211 },
212 _Quit => {
213 callback => sub { Gtk2->main_quit },
214 accelerator => '<ctrl>Q'
215 }
216 ]
217 },
218 _Edit => {
219 item_type => '<Branch>',
220 children => [
221 "_Undo" => {
222 callback => sub { $self->undo },
223 accelerator => "<ctrl>Z"
224 },
225 "_Redo" => {
226 callback => sub { $self->redo },
227 accelerator => "<ctrl>Y"
228 },
229 "_Attr Editor" => {
230 callback => sub { $self->show_attr_editor },
231 accelerator => "<ctrl>A"
232 },
233 "_Picker" => {
234 callback => sub { $self->open_pick_window },
235 accelerator => "<ctrl>P"
236 },
237 "_Stack View" => {
238 callback => sub { $self->show_stack_view },
239 accelerator => "<ctrl>V"
240 },
241
242 ]
243 },
244 _View => {
245 item_type => '<Branch>',
246 children => [
247 "Open _Attr Editor" => {
248 callback => sub { $self->show_attr_editor },
249 accelerator => "<ctrl>A"
250 },
251 "Open _Picker" => {
252 callback => sub { $self->open_pick_window },
253 accelerator => "<ctrl>P"
254 },
255 "Open _Stack View" => {
256 callback => sub { $self->show_stack_view },
257 accelerator => "<ctrl>V"
258 },
259
260 ]
261 }
262
263 ];
264
265 my $men =
266 Gtk2::SimpleMenu->new (
267 menu_tree => $menu_tree,
268 default_callback => \&default_cb,
269 );
270
271 $self->add_accel_group ($men->{accel_group});
272
273 return $men->{widget};
274 }
275
276 sub add_button {
277 my ($self, $table, $plcinfo, $lbl, $cb) = @_;
278
279 my ($lx, $ly) = @{$plcinfo->{next}};
280
281 unless ($lx < $plcinfo->{width}) {
282
283 $ly++;
284 $lx = 0;
285 }
286
287 $ly < $plcinfo->{height}
288 or die "too many buttons, make table bigger!";
289
290 $table->attach_defaults (my $btn = Gtk2::Button->new_with_label ($lbl), $lx, $lx + 1, $ly, $ly + 1);
291 $btn->signal_connect (clicked => $cb);
292
293 $plcinfo->{next} = [$lx + 1, $ly];
294 }
295
296 sub build_buttons {
297 my ($self) = @_;
298
299 my $tbl = Gtk2::Table->new (2, 2);
300 my $plcinfo = { width => 1, height => 3, next => [0, 0] };
301
302 $self->{edit_collection}{pick} = GCE::EditAction::Pick->new;
303 $self->{edit_collection}{place} = GCE::EditAction::Place->new;
304 $self->{edit_collection}{erase} = GCE::EditAction::Erase->new;
305
306 $self->add_button ($tbl, $plcinfo, "Pick", sub {
307 $self->{sel_editaction} = $self->{edit_collection}{pick};
308 $self->{edit_tool}->set_text ("Pick");
309 });
310 $self->add_button ($tbl, $plcinfo, "Place", sub {
311 $self->{sel_editaction} = $self->{edit_collection}{place};
312 $self->{edit_tool}->set_text ("Place");
313 });
314 $self->add_button ($tbl, $plcinfo, "Erase", sub {
315 $self->{sel_editaction} = $self->{edit_collection}{erase};
316 $self->{edit_tool}->set_text ("Erase");
317 });
318
319 return $tbl;
320 }
321
322
323 sub INIT_INSTANCE {
324 my ($self) = @_;
325
326 $MAINWIN = $self;
327
328 $self->set_title ("gce - main window");
329
330 $self->add (my $vb = Gtk2::VBox->new);
331 $vb->pack_start ($self->build_menu, 0, 1, 0);
332 $vb->pack_start (my $tbl = $self->build_buttons, 1, 1, 0);
333 $vb->pack_start ($self->{edit_tool} = Gtk2::Label->new, 0, 1, 0);
334 $vb->pack_start ($self->{pick_view} = Gtk2::Label->new, 0, 1, 0);
335
336 # XXX:load $ARGV _cleanly_?
337 $self->open_map_editor ($ARGV[0] || "$Crossfire::LIB/maps/dragonisland/advguild3");
338
339 $self->signal_connect ('delete-event' => sub {
340 Gtk2->main_quit;
341 });
342
343 main::set_pos_and_size ($self, $main::CFG->{main_window});
344 }
345
346 sub new_cb {
347 my ($self) = @_;
348 die "NOT IMPLEMENTED YET";
349 }
350
351 sub open_cb {
352 my ($self) = @_;
353
354 my $fc =
355 Gtk2::FileChooserDialog->new (
356 'gce - open map', undef, 'open', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok'
357 );
358
359 $fc->add_shortcut_folder ("$Crossfire::LIB/maps");
360 $fc->add_shortcut_folder ($_) for keys %{$self->{fc_last_folders}};
361 $fc->set_current_folder ($self->{fc_last_folder} || "$Crossfire::LIB/maps");
362
363 if ('ok' eq $fc->run) {
364
365 $self->{fc_last_folder} = $fc->get_current_folder;
366 $self->{fc_last_folders}->{$self->{fc_last_folder}}++;
367
368 $self->open_map_editor ($fc->get_filename);
369 }
370
371 $fc->destroy;
372 }
373
374 sub set_pick {
375 my ($self, $arch) = @_;
376
377 $self->{pick_arch} = $arch;
378 $self->{pick_view}->set_text ($arch->{_name});
379 }
380
381 sub get_pick {
382 my ($self) = @_;
383
384 # XXX: This is just to make sure that this function always returns something
385 return $self->{pick_arch} || { _name => 'platinacoin' };
386 }
387
388 =head1 AUTHOR
389
390 Marc Lehmann <schmorp@schmorp.de>
391 http://home.schmorp.de/
392
393 Robin Redeker <elmex@ta-sa.org>
394 http://www.ta-sa.org/
395
396 =cut
397 1;
398