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