/* This file is part of Cinaest. * * Copyright (C) 2009 Philipp Zabel * * Cinaest is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Cinaest is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Cinaest. If not, see . */ using Gtk; using Hildon; public class MovieWindow : StackableWindow { private MovieMenu menu; private Gdk.Pixbuf no_poster; private MoviePoster.Factory poster_factory; private HBox hbox; private Image image; private VBox details; private PannableArea pannable; private Label title_label; private Label rating_label; private Label cast_label; private Label plot; private bool portrait_mode; public MovieWindow.with_movie (Movie movie, MovieListStore store) { update_title (movie); // View menu menu = new MovieMenu (movie, store, this); set_main_menu (menu); // Poster image = new Image (); title_label = new Label (title_label_markup (movie)); title_label.wrap = true; title_label.use_markup = true; title_label.set_alignment (0.0f, 0.0f); var header = new HBox (false, 0); header.pack_start (title_label, true, true, 0); rating_label = new Label (rating_label_markup (movie)); rating_label.use_markup = true; rating_label.set_alignment (0.5f, 0.0f); header.pack_start (rating_label, false, false, MARGIN_DOUBLE); cast_label = new Label (cast_label_markup (movie)); cast_label.wrap = true; cast_label.use_markup = true; cast_label.set_alignment (0.0f, 0.0f); plot = new Label (movie.get_plot ()); plot.wrap = true; plot.set_alignment (0.0f, 0.0f); details = new VBox (false, MARGIN_DOUBLE); details.pack_start (header, false, false, 0); details.pack_start (cast_label, false, false, 0); details.pack_start (plot, false, false, 0); var pannable = new PannableArea (); var eventbox = new EventBox (); eventbox.add (details); eventbox.above_child = true; pannable.add_with_viewport (eventbox); hbox = new HBox (false, 0); hbox.pack_start (pannable, true, true, 0); portrait_mode = CinaestProgram.orientation.portrait; if (portrait_mode) { details.pack_start (image, false, false, 0); details.reorder_child (image, 0); plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1); } else { hbox.pack_start (image, false, false, MARGIN_DOUBLE); hbox.reorder_child (image, 0); plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1); pannable.set_size_request (-1, 424); } hbox.show_all (); add (hbox); // Connect signals menu.movie_deleted.connect (() => { destroy (); }); Gdk.Screen.get_default ().size_changed.connect (on_orientation_changed); movie.notify.connect (this.on_movie_changed); if (movie.poster != null && movie.poster.large != null) { image.pixbuf = movie.poster.large; } else { if (movie.poster != null && movie.poster.small != null) { // FIXME image.pixbuf = movie.poster.small.scale_simple (288, 400, Gdk.InterpType.HYPER); } else { // FIXME if (no_poster == null) try { no_poster = new Gdk.Pixbuf.from_file ("/usr/share/icons/hicolor/64x64/hildon/general_no_thumbnail.png"); } catch (Error e) { critical ("Missing general_no_thumbnail icon: %s\n", e.message); } image.pixbuf = no_poster; } try { poster_factory = MoviePoster.Factory.get_instance (); poster_factory.queue (movie, 288, 400, false, receive_poster); } catch (Error e) { warning ("Failed to queue poster request: %s\n", e.message); } } } private void update_title (Movie movie) { Gdk.Color color; this.ensure_style (); if (this.style.lookup_color ("SecondaryTextColor", out color)) set_markup ("%s (%d)".printf (movie.title, color.to_string (), movie.year)); else set_markup ("%s (%d)".printf (movie.title, movie.year)); } private string title_label_markup (Movie movie) { Gdk.Color color; this.ensure_style (); string year = ""; if (this.style.lookup_color ("SecondaryTextColor", out color)) { if (movie.year > 0) year = " (%d)".printf (color.to_string (), movie.year); return "%s%s\n%s".printf (movie.title, year, color.to_string (), movie.secondary); } else { if (movie.year > 0) year = " (%d)".printf (movie.year); return "%s%s\n%s".printf (movie.title, year, movie.secondary); } } private string rating_label_markup (Movie movie) { if (movie.rating > 0) return "%d.%d".printf (movie.rating / 10, movie.rating % 10); else return ""; } private string cast_label_markup (Movie movie) { List cast = movie.get_cast (); var markup = new StringBuilder (); Gdk.Color color; this.ensure_style (); if (this.style.lookup_color ("SecondaryTextColor", out color)) { foreach (Role role in cast) { if (markup.len > 0) markup.append (",\n"); markup.append_printf ("%s (%s)", display_name (role.actor_name), color.to_string (), role.character); } } else { foreach (Role role in cast) { if (markup.len > 0) markup.append (",\n"); markup.append_printf ("%s (%s)", display_name (role.actor_name), role.character); } } return markup.str; } private string display_name (string name) { string[] parts; if (name.has_suffix (")")) parts = name.ndup (name.length - 4).split (", "); else parts = name.split (", "); if (parts.length == 2) { return parts[1] + " " + parts[0]; } else { return name; } } private void receive_poster (Gdk.Pixbuf pixbuf, Movie movie) { var poster = new Poster(); poster.large = pixbuf; if (movie.poster != null) { poster.icon = movie.poster.icon; poster.small = movie.poster.small; } movie.poster = poster; } private void on_movie_changed (GLib.Object source, GLib.ParamSpec spec) { var movie = (Movie) source; if ((spec.name == "title") || (spec.name == "year")) { update_title (movie); title_label.set_markup (title_label_markup (movie)); } if (spec.name == "rating") { rating_label.set_markup (rating_label_markup (movie)); } if ((spec.name == "poster") && (movie.poster != null) && (movie.poster.large != null)) { image.pixbuf = movie.poster.large; } } private void on_orientation_changed (Gdk.Screen screen) { if (CinaestProgram.orientation.portrait == portrait_mode) return; portrait_mode = CinaestProgram.orientation.portrait; if (portrait_mode) { hbox.remove (image); details.pack_start (image, false, false, 0); details.reorder_child (image, 0); plot.set_size_request (480 - 2 * MARGIN_DOUBLE, -1); pannable.set_size_request (-1, -1); } else { details.remove (image); hbox.pack_start (image, false, false, MARGIN_DOUBLE); hbox.reorder_child (image, 0); pannable.set_size_request (-1, 424); plot.set_size_request (800 - 288 /* image */ - 3 * MARGIN_DOUBLE, -1); } } }