ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MainWindow.pm
Revision: 1.29
Committed: Sat Mar 11 04:54:45 2006 UTC (18 years, 3 months ago) by root
Branch: MAIN
Changes since 1.28: +1 -2 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 elmex 1.28 use GCE::Util;
28    
29 elmex 1.2 use strict;
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 root 1.26 main::write_cfg ("$Crossfire::VARDIR/gceconfig");
56 elmex 1.17 }
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 root 1.25
80 elmex 1.17 $w->open_map ($mapfile);
81    
82 root 1.25 ::set_pos_and_size ($w, $main::CFG->{map_window});
83 elmex 1.17
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 elmex 1.15 my ($self) = @_;
96    
97     return if defined $self->{sv};
98    
99 elmex 1.17 my $w = $self->{sv_win} = Gtk2::Window->new ('toplevel');
100 elmex 1.15 $w->set_title ('gce - stack view');
101 root 1.23 $w->signal_connect (delete_event => sub { delete $self->{sv}; 0 });
102 elmex 1.15 $w->add ($self->{sv} = GCE::StackView->new);
103 elmex 1.17
104     main::set_pos_and_size ($w, $main::CFG->{stack_view});
105    
106 elmex 1.15 $w->show_all;
107     }
108    
109     sub show_attr_editor {
110     my ($self) = @_;
111    
112 elmex 1.17 return if $self->{attr_edit};
113    
114 elmex 1.15 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 root 1.23 $w->signal_connect (delete_event => sub { delete $self->{attr_edit}; 0 });
118 elmex 1.17
119     main::set_pos_and_size ($w, $main::CFG->{attr_view});
120    
121 elmex 1.15 $w->show_all;
122     }
123    
124     sub update_attr_editor {
125 elmex 1.17 my ($self, $arch, $cb) = @_;
126 elmex 1.15
127     return unless $self->{attr_edit};
128    
129 elmex 1.17 $self->{attr_edit}->set_arch ($arch, $cb);
130 elmex 1.15 $self->{attr_edit_win}->set_title ("gce - edit $arch->{_name}");
131     }
132    
133     sub update_stack_view {
134 elmex 1.17 my ($self, $mapedit, $x, $y) = @_;
135 elmex 1.15
136     return unless $self->{sv};
137    
138 elmex 1.17 $self->{sv}->set_stack ($mapedit, $x, $y);
139 elmex 1.15 }
140    
141 elmex 1.17 sub open_pick_window {
142     my ($self, $layout) = @_;
143    
144 root 1.29 # XXX: Yes, also fix this, save _every_ pick window and their positions and their
145 elmex 1.17 # selection
146     my $p = GCE::PickWindow->new ();
147 elmex 1.15
148 elmex 1.17 push @{$self->{open_pick_windows}}, $p;
149    
150     my $idx = (@{$self->{open_pick_windows}}) - 1;
151 elmex 1.15
152 elmex 1.17 $p->signal_connect ('delete-event' => sub {
153     $self->{open_pick_windows}->[$idx] = undef;
154     });
155 elmex 1.10
156 elmex 1.17 if ($layout) {
157     main::set_pos_and_size ($p, $layout->{p_and_s});
158     }
159 elmex 1.10
160 elmex 1.17 $p->show_all;
161 elmex 1.10
162 elmex 1.17 $p->set_selection ($layout->{selection});
163 elmex 1.10 }
164    
165 elmex 1.13 sub build_menu {
166 elmex 1.1 my ($self) = @_;
167    
168 elmex 1.2 my $menu_tree = [
169     _File => {
170     item_type => '<Branch>',
171     children => [
172     _New => {
173     callback => sub { $self->new_cb },
174     accelerator => '<ctrl>N'
175     },
176     _Open => {
177     callback => sub { $self->open_cb },
178     accelerator => '<ctrl>O'
179     },
180 elmex 1.17 "_Save Layout" => {
181     callback => sub { $self->save_layout },
182     accelerator => '<ctrl>L'
183     },
184 elmex 1.2 _Quit => {
185     callback => sub { Gtk2->main_quit },
186     accelerator => '<ctrl>Q'
187     }
188     ]
189     },
190 root 1.24 _Dialogs => {
191 elmex 1.2 item_type => '<Branch>',
192     children => [
193 elmex 1.17 "_Attr Editor" => {
194     callback => sub { $self->show_attr_editor },
195     accelerator => "<ctrl>A"
196 elmex 1.2 },
197 elmex 1.17 "_Picker" => {
198     callback => sub { $self->open_pick_window },
199     accelerator => "<ctrl>P"
200     },
201     "_Stack View" => {
202     callback => sub { $self->show_stack_view },
203     accelerator => "<ctrl>V"
204     },
205 elmex 1.15 "Open _Attr Editor" => {
206     callback => sub { $self->show_attr_editor },
207     accelerator => "<ctrl>A"
208     },
209 elmex 1.9 "Open _Picker" => {
210 elmex 1.13 callback => sub { $self->open_pick_window },
211     accelerator => "<ctrl>P"
212 elmex 1.9 },
213 elmex 1.15 "Open _Stack View" => {
214 elmex 1.17 callback => sub { $self->show_stack_view },
215 elmex 1.15 accelerator => "<ctrl>V"
216     },
217    
218 elmex 1.2 ]
219 elmex 1.9 }
220 elmex 1.17
221 elmex 1.2 ];
222    
223 elmex 1.13 my $men =
224     Gtk2::SimpleMenu->new (
225     menu_tree => $menu_tree,
226     default_callback => \&default_cb,
227     );
228 elmex 1.10
229 elmex 1.2 $self->add_accel_group ($men->{accel_group});
230    
231 elmex 1.13 return $men->{widget};
232     }
233 elmex 1.10
234 elmex 1.17 sub add_button {
235     my ($self, $table, $plcinfo, $lbl, $cb) = @_;
236    
237     my ($lx, $ly) = @{$plcinfo->{next}};
238    
239     unless ($lx < $plcinfo->{width}) {
240    
241     $ly++;
242     $lx = 0;
243     }
244    
245     $ly < $plcinfo->{height}
246     or die "too many buttons, make table bigger!";
247    
248     $table->attach_defaults (my $btn = Gtk2::Button->new_with_label ($lbl), $lx, $lx + 1, $ly, $ly + 1);
249     $btn->signal_connect (clicked => $cb);
250    
251     $plcinfo->{next} = [$lx + 1, $ly];
252     }
253    
254     sub build_buttons {
255     my ($self) = @_;
256    
257     my $tbl = Gtk2::Table->new (2, 2);
258     my $plcinfo = { width => 1, height => 3, next => [0, 0] };
259    
260 elmex 1.28 $self->{edit_collection}{pick} = GCE::EditAction::Pick->new;
261 elmex 1.17 $self->{edit_collection}{place} = GCE::EditAction::Place->new;
262     $self->{edit_collection}{erase} = GCE::EditAction::Erase->new;
263    
264 elmex 1.28 $self->update_edit_tool ($self->{edit_collection}{pick}, "Pick");
265    
266 elmex 1.17 $self->add_button ($tbl, $plcinfo, "Pick", sub {
267 elmex 1.28 $self->update_edit_tool ($self->{edit_collection}{pick}, "Pick");;
268 elmex 1.17 });
269     $self->add_button ($tbl, $plcinfo, "Place", sub {
270 elmex 1.28 $self->update_edit_tool ($self->{edit_collection}{place}, "Place");;
271 elmex 1.17 });
272     $self->add_button ($tbl, $plcinfo, "Erase", sub {
273 elmex 1.28 $self->update_edit_tool ($self->{edit_collection}{erase}, "Erase");;
274 elmex 1.17 });
275    
276     return $tbl;
277     }
278 elmex 1.10
279 elmex 1.28 sub update_edit_tool {
280     my ($self, $tool, $name) = @_;
281    
282     $self->{edit_tool}->set_text ($name);
283     $self->{sel_editaction} = $tool;
284    
285     my $widget = $tool->tool_widget;
286    
287     for ($self->{edit_tool_cont}->get_children) {
288     $_->hide;
289     $self->{edit_tool_cont}->remove ($_);
290     }
291    
292     defined $widget or return;
293    
294     $self->{edit_tool_cont}->add ($widget);
295     $widget->show_all;
296     }
297    
298     sub update_pick_view {
299     my ($self, $arch) = @_;
300    
301     defined $arch->{_face}
302     or $arch = $Crossfire::ARCH{$arch->{_name}};
303    
304     $arch->{_face}
305     or warn "Arch $arch->{_name} has no face!";
306     $arch->{_face}
307     or return;
308    
309     fill_pb_from_arch ($self->{pick_view_pb}, $arch);
310     $self->{pick_view_img}->set_from_pixbuf ($self->{pick_view_pb});
311    
312     $self->{pick_view_lbl}->set_text ($arch->{_name});
313     }
314    
315 elmex 1.13 sub INIT_INSTANCE {
316     my ($self) = @_;
317 elmex 1.10
318 root 1.24 $::MAINWIN = $self;
319 elmex 1.15
320 elmex 1.13 $self->set_title ("gce - main window");
321 elmex 1.10
322 elmex 1.28 $self->{edit_tool} = Gtk2::Label->new;
323     $self->{edit_tool_cont} = Gtk2::VBox->new;
324    
325 elmex 1.13 $self->add (my $vb = Gtk2::VBox->new);
326     $vb->pack_start ($self->build_menu, 0, 1, 0);
327 elmex 1.28
328     $vb->pack_start (my $hb = $self->{pick_view_hb} = Gtk2::HBox->new, 0, 1, 0);
329     $hb->pack_start ($self->{pick_view_img} = Gtk2::Image->new, 0, 1, 0);
330     $hb->pack_start ($self->{pick_view_lbl} = Gtk2::Label->new, 0, 1, 0);
331     $self->{pick_view_pb} = new_arch_pb ();
332    
333     $vb->pack_start (Gtk2::HSeparator->new, 0, 1, 0);
334     $vb->pack_start (my $tbl = $self->build_buttons, 0, 1, 0);
335    
336     $vb->pack_start (Gtk2::HSeparator->new, 0, 1, 0);
337     $vb->pack_start ($self->{edit_tool}, 0, 1, 0);
338    
339     $vb->pack_start (Gtk2::HSeparator->new, 0, 1, 0);
340     $vb->pack_start ($self->{edit_tool_cont}, 0, 1, 0);
341 elmex 1.10
342 elmex 1.13 # XXX:load $ARGV _cleanly_?
343 root 1.27 $self->open_map_editor ($_)
344     for @ARGV;
345 root 1.11
346 elmex 1.13 $self->signal_connect ('delete-event' => sub {
347     Gtk2->main_quit;
348 elmex 1.10 });
349 elmex 1.17
350 root 1.24 ::set_pos_and_size ($self, $main::CFG->{main_window});
351 elmex 1.2 }
352    
353     sub new_cb {
354     my ($self) = @_;
355 root 1.25 warn "new map not yet implemented\n";
356 elmex 1.2 }
357    
358 root 1.25 sub new_filechooser {
359 elmex 1.2 my ($self) = @_;
360    
361 root 1.25 my $fc = new Gtk2::FileChooserDialog (
362 elmex 1.13 'gce - open map', undef, 'open', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok'
363     );
364    
365 root 1.27 $fc->add_shortcut_folder ("$Crossfire::LIB/maps") if -d "$Crossfire::LIB/maps";
366 elmex 1.13 $fc->add_shortcut_folder ($_) for keys %{$self->{fc_last_folders}};
367 elmex 1.10 $fc->set_current_folder ($self->{fc_last_folder} || "$Crossfire::LIB/maps");
368 elmex 1.2
369 root 1.25 $fc
370     }
371    
372     sub open_cb {
373     my ($self) = @_;
374    
375     my $fc = $self->new_filechooser;
376    
377 elmex 1.2 if ('ok' eq $fc->run) {
378 elmex 1.13
379 elmex 1.10 $self->{fc_last_folder} = $fc->get_current_folder;
380 elmex 1.13 $self->{fc_last_folders}->{$self->{fc_last_folder}}++;
381 elmex 1.17
382     $self->open_map_editor ($fc->get_filename);
383 elmex 1.2 }
384    
385     $fc->destroy;
386     }
387    
388 elmex 1.17 sub set_pick {
389     my ($self, $arch) = @_;
390    
391     $self->{pick_arch} = $arch;
392 elmex 1.28 $self->update_pick_view ($arch);
393 elmex 1.17 }
394    
395     sub get_pick {
396     my ($self) = @_;
397    
398     # XXX: This is just to make sure that this function always returns something
399     return $self->{pick_arch} || { _name => 'platinacoin' };
400     }
401    
402 elmex 1.1 =head1 AUTHOR
403    
404     Marc Lehmann <schmorp@schmorp.de>
405     http://home.schmorp.de/
406    
407     Robin Redeker <elmex@ta-sa.org>
408     http://www.ta-sa.org/
409    
410     =cut
411     1;
412