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

File Contents

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