]> mj.ucw.cz Git - anim.git/blob - AA/UI.pm
Clean up old cruft.
[anim.git] / AA / UI.pm
1 package AA::UI;
2
3 sub new($$) {
4         my ($class, $name) = @_;
5         if ($name eq "") {
6                 return AA::UI::GTK->new(1);
7         } elsif ($name eq "gtk") {
8                 return AA::UI::GTK->new(0);
9         } elsif ($name =~ /\.pdf$/) {
10                 return AA::UI::PDF->new($name);
11         } elsif ($name =~ /\.png$/) {
12                 return AA::UI::PNG->new($name);
13         }
14 }
15
16 package AA::UI::GTK;
17
18 @ISA = ('AA::UI');
19
20 sub new($$) {
21         my ($class, $mode) = @_;
22         my $ui = {
23                 MODE => $mode,
24         };
25         return bless($ui, $class);
26 }
27
28 my $u_scenario;
29 my $u_scene;
30 my @u_scenes = ();
31
32 my $window;
33 my $cairo;
34 my $area;
35 my $pixmap;
36 my $timer;
37 my $stopped = 1;
38 my $fullscreen = 0;
39 my ($lastw, $lasth, $lastd) = (-1, -1, -1);
40 my ($pixw, $pixh) = (-1, -1);
41
42 sub draw($) {
43         my ($force) = @_;
44         my $win = $area->window;
45         my $wgc = Gtk2::Gdk::GC->new($win);
46         my $alloc = $area->allocation;
47         my $w = $alloc->width;
48         my $h = $alloc->height;
49         my $d = $win->get_depth;
50         # print "Area $w x $h x $d, xx=$xx\n";
51
52         if (!defined($pixmap) || $lastw != $w || $lasth != $h || $lastd != $d) {
53                 ($lastw, $lasth, $lastd) = ($w, $h, $d);
54                 if ($w/$h >= 4/3) {
55                         $pixh = $h;
56                         $pixw = int($h/3*4);
57                 } else {
58                         $pixw = $w;
59                         $pixh = int($w/4*3);
60                 }
61                 print "Resized to ${w}x${h}, pixmap size ${pixw}x${pixh}\n";
62
63                 $pixmap = Gtk2::Gdk::Pixmap->new($win, $pixw, $pixh, $d);
64                 $cairo = Gtk2::Gdk::Cairo::Context->create($pixmap);
65                 $cairo->select_font_face('URW Palladio L', 'normal', 'normal');
66                 my $scale = $pixw/1024;
67                 $cairo->scale($scale, $scale);
68         }
69
70         if ($force) {
71                 $wgc->set_rgb_background(0);
72                 $wgc->set_rgb_foreground(0);
73                 $win->draw_rectangle($wgc, 1, 0, 0, $w, $h);
74         }
75
76         $cairo->rectangle(0, 0, 1024, 768);
77         $cairo->set_source_rgb(0, 0, 0);
78         $cairo->fill;
79
80         if (@u_scenes) {
81                 $u_scenes[$u_scene]->Draw($cairo);
82                 $cairo->set_source_rgb(.5, .5, .5);
83                 $cairo->set_font_size(15);
84                 $cairo->move_to(950,750);
85                 $cairo->show_text($u_scene . "/" . $#u_scenes);
86         } else {
87                 AA->calculate;
88                 AA->draw($cairo);
89         }
90
91         $win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $pixw, $pixh);
92 }
93
94 sub step() {
95         AA::Anim->step;
96         draw(0);
97 }
98
99 sub prepare() {
100         $window = Gtk2::Window->new ('toplevel');
101         $area = Gtk2::DrawingArea->new();
102         $area->signal_connect("expose-event" => sub {
103                 draw(1);
104                 if (!defined $timer) {
105                         $timer = Glib::Timeout->add(30, sub { $stopped || step(); return 1; });
106                 }
107         });
108         $area->set_flags('can-focus');
109         # $area->add_events('key-press-mask');
110         $area->signal_connect('key-press-event' => sub {
111                 my ($w, $evt) = @_;
112                 my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval);
113                 print "Pressed key $k\n";
114                 if ($k eq "Escape") {
115                         Gtk2->main_quit;
116                 } elsif ($k eq "f") {
117                         if ($fullscreen = !$fullscreen) {
118                                 $window->fullscreen;
119                         } else {
120                                 $window->unfullscreen;
121                         }
122                 } elsif ($k eq "space" || $k eq "Right" || $k eq "Page_Down") {
123                         if (@u_scenes) {
124                                 if ($u_scene+1 < @u_scenes) {
125                                         $u_scene++;
126                                         draw(0);
127                                 }
128                         } else {
129                                 if ($u_scene+1 < @$u_scenario) {
130                                         $u_scene++;
131                                         &{$u_scenario->[$u_scene]};
132                                         draw(0);
133                                 }
134                         }
135                 } elsif ($k eq "BackSpace" || $k eq "Left" || $k eq "Page_Up") {
136                         if (@u_scenes && $u_scene) {
137                                 $u_scene--;
138                                 draw(0);
139                         }
140                 } elsif ($k eq "Home" || $k eq "0") {
141                         if (@u_scenes) {
142                                 $u_scene = 0;
143                                 draw(0);
144                         }
145                 } elsif ($k eq "End" || $k eq "9") {
146                         if (@u_scenes) {
147                                 $u_scene = $#u_scenes;
148                                 draw(0);
149                         }
150                 }
151         });
152
153         $window->signal_connect ("delete-event" => sub { Gtk2->main_quit });
154         $window->set_title("Brum");
155         $window->set_wmclass("brum", "Brum");
156         $window->set_default_size(640, 480);
157         $window->add ($area);
158         $window->show_all;
159 }
160
161 sub RunScenario($$) {
162         my ($ui, $scenario) = @_;
163
164         if ($ui->{MODE}) {
165                 print "Rendering...\n";
166                 foreach my $s (@$scenario) {
167                         &$s;
168                         AA->calculate;
169                         push @u_scenes, AA::Scene->new();
170                 }
171                 print "Ready.\n";
172         } else {
173                 $u_scenario = $scenario;
174                 &{$scenario->[0]};
175         }
176
177         $u_scene = 0;
178         prepare();
179         Gtk2->main;
180 }
181
182 package AA::UI::PDF;
183
184 @ISA = ('AA::UI');
185
186 sub new($$) {
187         my ($class, $name) = @_;
188         my $ui = { };
189         $ui->{SURF} = Cairo::PdfSurface->create($name, 512, 384) or die "Unable to create PDF surface $name\n";
190         $ui->{CAIRO} = Cairo::Context->create($ui->{SURF});
191         $ui->{CAIRO}->scale(.5, .5);
192         return bless($ui, $class);
193 }
194
195 sub RunScenario($$$) {
196         my ($ui, $scenario) = @_;
197         my $page = 0;
198         foreach my $s (@$scenario) {
199                 $page++;
200                 print "### Page $page ###\n";
201                 &$s();
202                 AA->calculate;
203                 AA->draw($ui->{CAIRO});
204                 $ui->{CAIRO}->show_page;
205         }
206 }
207
208 package AA::UI::PNG;
209
210 @ISA = ('AA::UI');
211
212 sub new($$) {
213         my ($class, $name) = @_;
214         my $ui = { };
215         $ui->{NAME} = $name;
216         $ui->{SURF} = Cairo::ImageSurface->create('argb32', 1024, 768) or die "Unable to create image surface $name\n";
217         $ui->{CAIRO} = Cairo::Context->create($ui->{SURF});
218         return bless($ui, $class);
219 }
220
221 sub RunScenario($$$) {
222         my ($ui, $scenario) = @_;
223         my $cairo = $ui->{CAIRO};
224         my $page = 0;
225         foreach my $s (@$scenario) {
226                 $page++;
227                 print "### Page $page ###\n";
228                 &$s();
229                 AA->calculate;
230                 AA->draw($cairo);
231                 $cairo->show_page;
232                 my $name = sprintf($ui->{NAME}, $page);
233                 $ui->{SURF}->write_to_png($name) or die "Unable to write to $name\n";
234         }
235 }
236
237 1;