1 /* This file is part of Cinaest.
3 * Copyright (C) 2009 Philipp Zabel
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.
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.
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/>.
22 public class MovieWindow : StackableWindow {
23 private MovieMenu menu;
24 private Gdk.Pixbuf no_poster;
25 private MoviePoster.Factory poster_factory;
29 private PannableArea pannable;
30 private Label title_label;
31 private Label rating_label;
32 private Label cast_label;
34 private bool portrait_mode;
36 public MovieWindow.with_movie (Movie movie, MovieListStore store) {
40 menu = new MovieMenu (movie, store, this);
47 title_label = new Label (title_label_markup (movie));
48 title_label.wrap = true;
49 title_label.use_markup = true;
50 title_label.set_alignment (0.0f, 0.0f);
52 var header = new HBox (false, 0);
53 header.pack_start (title_label, true, true, 0);
55 rating_label = new Label (rating_label_markup (movie));
56 rating_label.use_markup = true;
57 rating_label.set_alignment (0.5f, 0.0f);
58 header.pack_start (rating_label, false, false, MARGIN_DOUBLE);
60 cast_label = new Label (cast_label_markup (movie));
61 cast_label.wrap = true;
62 cast_label.use_markup = true;
63 cast_label.set_alignment (0.0f, 0.0f);
65 plot = new Label (movie.get_plot ());
67 plot.set_alignment (0.0f, 0.0f);
69 details = new VBox (false, MARGIN_DOUBLE);
70 details.pack_start (header, false, false, 0);
71 details.pack_start (cast_label, false, false, 0);
72 details.pack_start (plot, false, false, 0);
74 var pannable = new PannableArea ();
75 var eventbox = new EventBox ();
76 eventbox.add (details);
77 eventbox.above_child = true;
78 pannable.add_with_viewport (eventbox);
80 hbox = new HBox (false, 0);
81 hbox.pack_start (pannable, true, true, 0);
83 portrait_mode = CinaestProgram.orientation.portrait;
85 details.pack_start (image, false, false, 0);
86 details.reorder_child (image, 0);
87 plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1);
89 hbox.pack_start (image, false, false, MARGIN_DOUBLE);
90 hbox.reorder_child (image, 0);
91 plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1);
92 pannable.set_size_request (-1, 424);
99 menu.movie_deleted.connect (() => { destroy (); });
100 Gdk.Screen.get_default ().size_changed.connect (on_orientation_changed);
101 movie.notify.connect (this.on_movie_changed);
103 if (movie.poster != null && movie.poster.large != null) {
104 image.pixbuf = movie.poster.large;
106 if (movie.poster != null && movie.poster.small != null) {
108 image.pixbuf = movie.poster.small.scale_simple (288, 400, Gdk.InterpType.HYPER);
111 if (no_poster == null) try {
112 no_poster = new Gdk.Pixbuf.from_file ("/usr/share/icons/hicolor/64x64/hildon/general_no_thumbnail.png");
114 critical ("Missing general_no_thumbnail icon: %s\n", e.message);
116 image.pixbuf = no_poster;
119 poster_factory = MoviePoster.Factory.get_instance ();
120 poster_factory.queue (movie, 288, 400, false, receive_poster);
122 warning ("Failed to queue poster request: %s\n", e.message);
127 private void update_title (Movie movie) {
129 this.ensure_style ();
130 if (this.style.lookup_color ("SecondaryTextColor", out color))
131 set_markup ("%s <span size=\"small\" fgcolor=\"%s\">(%d)</span>".printf (movie.title, color.to_string (), movie.year));
133 set_markup ("%s <small>(%d)</small>".printf (movie.title, movie.year));
136 private string title_label_markup (Movie movie) {
138 this.ensure_style ();
140 if (this.style.lookup_color ("SecondaryTextColor", out color)) {
142 year = " <span fgcolor=\"%s\">(%d)</span>".printf (color.to_string (), movie.year);
143 return "<big><b>%s</b></big>%s\n<span size=\"small\" fgcolor=\"%s\">%s</span>".printf (movie.title, year, color.to_string (), movie.secondary);
146 year = " (%d)".printf (movie.year);
147 return "<big><b>%s</b></big>%s\n<small>%s</small>".printf (movie.title, year, movie.secondary);
151 private string rating_label_markup (Movie movie) {
152 if (movie.rating > 0)
153 return "<big><b>%d.%d</b></big>".printf (movie.rating / 10, movie.rating % 10);
158 private string cast_label_markup (Movie movie) {
159 List<Role> cast = movie.get_cast ();
160 var markup = new StringBuilder ();
162 this.ensure_style ();
164 if (this.style.lookup_color ("SecondaryTextColor", out color)) {
165 foreach (Role role in cast) {
167 markup.append (",\n");
168 markup.append_printf ("%s <span size=\"small\" fgcolor=\"%s\">(%s)</span>", display_name (role.actor_name), color.to_string (), role.character);
171 foreach (Role role in cast) {
173 markup.append (",\n");
174 markup.append_printf ("%s <small>(%s)</small>", display_name (role.actor_name), role.character);
181 private string display_name (string name) {
183 if (name.has_suffix (")"))
184 parts = name.ndup (name.length - 4).split (", ");
186 parts = name.split (", ");
187 if (parts.length == 2) {
188 return parts[1] + " " + parts[0];
194 private void receive_poster (Gdk.Pixbuf pixbuf, Movie movie) {
195 var poster = new Poster();
197 poster.large = pixbuf;
198 if (movie.poster != null) {
199 poster.icon = movie.poster.icon;
200 poster.small = movie.poster.small;
202 movie.poster = poster;
205 private void on_movie_changed (GLib.Object source, GLib.ParamSpec spec) {
206 var movie = (Movie) source;
208 if ((spec.name == "title") || (spec.name == "year")) {
209 update_title (movie);
210 title_label.set_markup (title_label_markup (movie));
212 if (spec.name == "rating") {
213 rating_label.set_markup (rating_label_markup (movie));
215 if ((spec.name == "poster") && (movie.poster != null) && (movie.poster.large != null)) {
216 image.pixbuf = movie.poster.large;
220 private void on_orientation_changed (Gdk.Screen screen) {
221 if (CinaestProgram.orientation.portrait == portrait_mode)
224 portrait_mode = CinaestProgram.orientation.portrait;
227 details.pack_start (image, false, false, 0);
228 details.reorder_child (image, 0);
229 plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1);
230 pannable.set_size_request (-1, -1);
232 details.remove (image);
233 hbox.pack_start (image, false, false, MARGIN_DOUBLE);
234 hbox.reorder_child (image, 0);
235 pannable.set_size_request (-1, 424);
236 plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1);