ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/gde/GCE/MainWindow.pm
Revision: 1.30
Committed: Sun Mar 12 12:18:55 2006 UTC (18 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.29: +5 -5 lines
Log Message:
Implemented first parts of the new attribute editor.

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 GCE::Util;
28
29 use strict;
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 ("$Crossfire::VARDIR/gceconfig");
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
80 $w->open_map ($mapfile);
81
82 ::set_pos_and_size ($w, $main::CFG->{map_window}, 500, 500, 200, 0);
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}, 150, 250);
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}, 200, 200);
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 positions 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}, 200, 200);
158 }
159
160 $p->show_all;
161
162 $p->set_selection ($layout->{selection});
163 }
164
165 sub build_menu {
166 my ($self) = @_;
167
168 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 "_Save Layout" => {
181 callback => sub { $self->save_layout },
182 accelerator => '<ctrl>L'
183 },
184 _Quit => {
185 callback => sub { Gtk2->main_quit },
186 accelerator => '<ctrl>Q'
187 }
188 ]
189 },
190 _Dialogs => {
191 item_type => '<Branch>',
192 children => [
193 "_Attr Editor" => {
194 callback => sub { $self->show_attr_editor },
195 accelerator => "<ctrl>A"
196 },
197 "_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 "Open _Attr Editor" => {
206 callback => sub { $self->show_attr_editor },
207 accelerator => "<ctrl>A"
208 },
209 "Open _Picker" => {
210 callback => sub { $self->open_pick_window },
211 accelerator => "<ctrl>P"
212 },
213 "Open _Stack View" => {
214 callback => sub { $self->show_stack_view },
215 accelerator => "<ctrl>V"
216 },
217
218 ]
219 }
220
221 ];
222
223 my $men =
224 Gtk2::SimpleMenu->new (
225 menu_tree => $menu_tree,
226 default_callback => \&default_cb,
227 );
228
229 $self->add_accel_group ($men->{accel_group});
230
231 return $men->{widget};
232 }
233
234 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 $self->{edit_collection}{pick} = GCE::EditAction::Pick->new;
261 $self->{edit_collection}{place} = GCE::EditAction::Place->new;
262 $self->{edit_collection}{erase} = GCE::EditAction::Erase->new;
263
264 $self->update_edit_tool ($self->{edit_collection}{pick}, "Pick");
265
266 $self->add_button ($tbl, $plcinfo, "Pick", sub {
267 $self->update_edit_tool ($self->{edit_collection}{pick}, "Pick");;
268 });
269 $self->add_button ($tbl, $plcinfo, "Place", sub {
270 $self->update_edit_tool ($self->{edit_collection}{place}, "Place");;
271 });
272 $self->add_button ($tbl, $plcinfo, "Erase", sub {
273 $self->update_edit_tool ($self->{edit_collection}{erase}, "Erase");;
274 });
275
276 return $tbl;
277 }
278
279 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 sub INIT_INSTANCE {
316 my ($self) = @_;
317
318 $::MAINWIN = $self;
319
320 $self->set_title ("gce - main window");
321
322 $self->{edit_tool} = Gtk2::Label->new;
323 $self->{edit_tool_cont} = Gtk2::VBox->new;
324
325 $self->add (my $vb = Gtk2::VBox->new);
326 $vb->pack_start ($self->build_menu, 0, 1, 0);
327
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
342 # XXX:load $ARGV _cleanly_?
343 $self->open_map_editor ($_)
344 for @ARGV;
345
346 $self->signal_connect ('delete-event' => sub {
347 Gtk2->main_quit;
348 });
349
350 ::set_pos_and_size ($self, $main::CFG->{main_window}, 150, 200, 0, 0);
351 }
352
353 sub new_cb {
354 my ($self) = @_;
355 warn "new map not yet implemented\n";
356 }
357
358 sub new_filechooser {
359 my ($self) = @_;
360
361 my $fc = new Gtk2::FileChooserDialog (
362 'gce - open map', undef, 'open', 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok'
363 );
364
365 $fc->add_shortcut_folder ("$Crossfire::LIB/maps") if -d "$Crossfire::LIB/maps";
366 $fc->add_shortcut_folder ($_) for keys %{$self->{fc_last_folders}};
367 $fc->set_current_folder ($self->{fc_last_folder} || "$Crossfire::LIB/maps");
368
369 $fc
370 }
371
372 sub open_cb {
373 my ($self) = @_;
374
375 my $fc = $self->new_filechooser;
376
377 if ('ok' eq $fc->run) {
378
379 $self->{fc_last_folder} = $fc->get_current_folder;
380 $self->{fc_last_folders}->{$self->{fc_last_folder}}++;
381
382 $self->open_map_editor ($fc->get_filename);
383 }
384
385 $fc->destroy;
386 }
387
388 sub set_pick {
389 my ($self, $arch) = @_;
390
391 $self->{pick_arch} = $arch;
392 $self->update_pick_view ($arch);
393 }
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 =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