Poster downloading update
[cinaest] / src / movie-window.vala
1 /* This file is part of Cinaest.
2  *
3  * Copyright (C) 2009 Philipp Zabel
4  *
5  * Cinaest is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Cinaest is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Cinaest. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 using Gtk;
20 using Hildon;
21
22 public class MovieWindow : StackableWindow {
23         private MovieMenu menu;
24         private Gdk.Pixbuf no_poster;
25         private MoviePoster.Factory poster_factory;
26         private HBox hbox;
27         private Image image;
28         private VBox details;
29         private PannableArea pannable;
30         private Label title_label;
31         private Label rating_label;
32         private Label plot;
33         private bool portrait_mode;
34
35         public MovieWindow.with_movie (Movie movie, MovieListStore store) {
36                 update_title (movie);
37
38                 // View menu
39                 menu = new MovieMenu (movie, store, this);
40
41                 set_main_menu (menu);
42
43                 // Poster
44                 image = new Image ();
45
46                 title_label = new Label (title_label_markup (movie));
47                 title_label.wrap = true;
48                 title_label.use_markup = true;
49                 title_label.set_alignment (0.0f, 0.0f);
50
51                 var header = new HBox (false, 0);
52                 header.pack_start (title_label, true, true, 0);
53
54                 rating_label = new Label (rating_label_markup (movie));
55                 rating_label.use_markup = true;
56                 rating_label.set_alignment (0.5f, 0.0f);
57                 header.pack_start (rating_label, false, false, MARGIN_DOUBLE);
58
59                 plot = new Label (movie.get_plot ());
60                 plot.wrap = true;
61                 plot.set_alignment (0.0f, 0.0f);
62
63                 details = new VBox (false, MARGIN_DOUBLE);
64                 details.pack_start (header, false, false, 0);
65                 details.pack_start (plot, false, false, 0);
66
67                 var pannable = new PannableArea ();
68                 var eventbox = new EventBox ();
69                 eventbox.add (details);
70                 eventbox.above_child = true;
71                 pannable.add_with_viewport (eventbox);
72
73                 hbox = new HBox (false, 0);
74                 hbox.pack_start (pannable, true, true, 0);
75
76                 portrait_mode = CinaestProgram.orientation.portrait;
77                 if (portrait_mode) {
78                         details.pack_start (image, false, false, 0);
79                         details.reorder_child (image, 0);
80                         plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1);
81                 } else {
82                         hbox.pack_start (image, false, false, MARGIN_DOUBLE);
83                         hbox.reorder_child (image, 0);
84                         plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1);
85                         pannable.set_size_request (-1, 424);
86                 }
87
88                 hbox.show_all ();
89                 add (hbox);
90
91                 // Connect signals
92                 menu.movie_deleted.connect (() => { destroy (); });
93                 Gdk.Screen.get_default ().size_changed.connect (on_orientation_changed);
94                 movie.notify.connect (this.on_movie_changed);
95
96                 if (movie.poster != null && movie.poster.large != null) {
97                         image.pixbuf = movie.poster.large;
98                 } else {
99                         if (movie.poster != null && movie.poster.small != null) {
100                                 // FIXME
101                                 image.pixbuf = movie.poster.small.scale_simple (288, 400, Gdk.InterpType.HYPER);
102                         } else {
103                                 // FIXME
104                                 if (no_poster == null) try {
105                                         no_poster = new Gdk.Pixbuf.from_file ("/usr/share/icons/hicolor/64x64/hildon/general_no_thumbnail.png");
106                                 } catch (Error e) {
107                                         critical ("Missing general_no_thumbnail icon: %s\n", e.message);
108                                 }
109                                 image.pixbuf = no_poster;
110                         }
111                         try {
112                                 poster_factory = MoviePoster.Factory.get_instance ();
113                                 poster_factory.queue (movie, 288, 400, false, receive_poster);
114                         } catch (Error e) {
115                                 warning ("Failed to queue poster request: %s\n", e.message);
116                         }
117                 }
118         }
119
120         private void update_title (Movie movie) {
121                 Gdk.Color color;
122                 this.ensure_style ();
123                 if (this.style.lookup_color ("SecondaryTextColor", out color))
124                         set_markup ("%s <span size=\"small\" fgcolor=\"%s\">(%d)</span>".printf (movie.title, color.to_string (), movie.year));
125                 else
126                         set_markup ("%s <small>(%d)</small>".printf (movie.title, movie.year));
127         }
128
129         private string title_label_markup (Movie movie) {
130                 Gdk.Color color;
131                 this.ensure_style ();
132                 string year = "";
133                 if (this.style.lookup_color ("SecondaryTextColor", out color)) {
134                         if (movie.year > 0)
135                                 year = " <span fgcolor=\"%s\">(%d)</span>".printf (color.to_string (), movie.year);
136                         return "<big><b>%s</b></big>%s\n<span size=\"small\" fgcolor=\"%s\">%s</span>".printf (movie.title, year, color.to_string (), movie.secondary);
137                 } else {
138                         if (movie.year > 0)
139                                 year = " (%d)".printf (movie.year);
140                         return "<big><b>%s</b></big>%s\n<small>%s</small>".printf (movie.title, year, movie.secondary);
141                 }
142         }
143
144         private string rating_label_markup (Movie movie) {
145                 if (movie.rating > 0)
146                         return "<big><b>%d.%d</b></big>".printf (movie.rating / 10, movie.rating % 10);
147                 else
148                         return "";
149         }
150
151         private void receive_poster (Gdk.Pixbuf pixbuf, Movie movie) {
152                 var poster = new Poster();
153
154                 poster.large = pixbuf;
155                 if (movie.poster != null) {
156                         poster.icon = movie.poster.icon;
157                         poster.small = movie.poster.small;
158                 }
159                 movie.poster = poster;
160         }
161
162         private void on_movie_changed (GLib.Object source, GLib.ParamSpec spec) {
163                 var movie = (Movie) source;
164
165                 if ((spec.name == "title") || (spec.name == "year")) {
166                         update_title (movie);
167                         title_label.set_markup (title_label_markup (movie));
168                 }
169                 if (spec.name == "rating") {
170                         rating_label.set_markup (rating_label_markup (movie));
171                 }
172                 if ((spec.name == "poster") && (movie.poster != null) && (movie.poster.large != null)) {
173                         image.pixbuf = movie.poster.large;
174                 }
175         }
176
177         private void on_orientation_changed (Gdk.Screen screen) {
178                 if (CinaestProgram.orientation.portrait == portrait_mode)
179                         return;
180
181                 portrait_mode = CinaestProgram.orientation.portrait;
182                 if (portrait_mode) {
183                         hbox.remove (image);
184                         details.pack_start (image, false, false, 0);
185                         details.reorder_child (image, 0);
186                         plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1);
187                         pannable.set_size_request (-1, -1);
188                 } else {
189                         details.remove (image);
190                         hbox.pack_start (image, false, false, MARGIN_DOUBLE);
191                         hbox.reorder_child (image, 0);
192                         pannable.set_size_request (-1, 424);
193                         plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1);
194                 }
195         }
196 }
197