Archive / / / / / Echo.UI.TreeModels.PlaySourceModel.vala
2008-12-02 07:05:06 UTC
previous next
/* vim: set noexpandtab tabstop=4 shiftwidth=4 nowrap textwidth=100 * * Echo Media Player * Copyright (C) 2008 Shane O'Connell * * [ The original file includes a copyright header in this location describing * the file as being released under the terms of the GNU General Public * License. It has been removed in order to display the file as part of the * archive. ] */ using Echo.Core; using Echo.Interfaces; public class Echo.UI.TreeModels.PlaySourceModel : GLib.Object, Gtk.TreeModel { // TODO make TreeIter's use IPlaySourceTrackRef's so that they don't need to // be invalidated private IPlaySource source; private ITrack _last_known_track = null; private int _last_known_num_tracks; private int stamp = 0; public enum Column { TITLE = 0, ARTIST = 1, ALBUM = 2, TRACK_NUMBER = 3, YEAR = 4, URI = 5, PLAYING = 6, RATING = 7 } public PlaySourceModel(IPlaySource source) { this.source = source; _last_known_num_tracks = source.get_num_tracks(); source.track_removed += (source, index) => { _last_known_num_tracks = source.get_num_tracks(); stamp++; this.row_deleted(get_path_from_index(index, false)); }; source.track_inserted += (source, index) => { _last_known_num_tracks = source.get_num_tracks(); stamp++; Gtk.TreeIter iter; get_iter_from_index(out iter, index); this.row_inserted(get_path_from_index(index), iter); }; source.track_changed += (source, index) => { Gtk.TreeIter iter; get_iter_from_index(out iter, index); this.row_changed(get_path_from_index(index), iter); }; source.source_refreshed += (source) => { Gtk.TreeIter iter; for (int i = 0; i < _last_known_num_tracks; i++) { if (i < source.get_num_tracks()) { get_iter_from_index(out iter, i); this.row_changed(get_path_from_index(i), iter); } else this.row_deleted(get_path_from_index(i, false)); } if (source.get_num_tracks() > _last_known_num_tracks) for (int i = _last_known_num_tracks; i < source.get_num_tracks(); i++) { get_iter_from_index(out iter, i); this.row_inserted(get_path_from_index(i), iter); } }; Services.playback().track_changed += (playback_manager, is_automatic) => { Gtk.TreeIter iter; // Update the "Playing" field on the old track if (_last_known_track != null && _last_known_track.valid) { get_iter_from_index(out iter, _last_known_track.index); this.row_changed(get_path_from_index(_last_known_track.index), iter); _last_known_track = null; } if (playback_manager.current_track != null && playback_manager.current_track.source == this.source) { // Update the "Playing" field on the new track get_iter_from_index(out iter, playback_manager.current_track.index); this.row_changed(get_path_from_index(playback_manager.current_track.index), iter); _last_known_track = playback_manager.current_track; } }; // Should not be necessary /*Services.playback().state_changed += (playback_manager) => { if (playback_manager.current_track == null && _last_known_track != null && _last_known_track.valid) { Gtk.TreeIter iter; get_iter_from_index(out iter, _last_known_track.index); this.row_changed(get_path_from_index(_last_known_track.index), iter); _last_known_track = null; } };*/ } public int get_n_columns() { return 8; // TODO Can this come directly from the enum? } public Type get_column_type(int index) { switch (index) { case Column.TITLE: return typeof(string); case Column.ARTIST: return typeof(string); case Column.ALBUM: return typeof(string); case Column.YEAR: return typeof(int); case Column.TRACK_NUMBER: return typeof(int); case Column.URI: return typeof(string); case Column.PLAYING: return typeof(bool); case Column.RATING: return typeof(int); default: assert_not_reached(); } } public void get_value(Gtk.TreeIter iter, int column, ref GLib.Value value) { int index = get_index_from_iter(iter); switch(column) { case Column.TITLE: value.init(typeof(string)); value.set_string(source.get_track(index).title); break; case Column.ARTIST: value.init(typeof(string)); value.set_string(source.get_track(index).artist); break; case Column.ALBUM: value.init(typeof(string)); value.set_string(source.get_track(index).album); break; case Column.YEAR: value.init(typeof(int)); value.set_int((int)source.get_track(index).release_year); break; case Column.TRACK_NUMBER: value.init(typeof(int)); value.set_int(source.get_track(index).track_number); break; case Column.URI: value.init(typeof(string)); value.set_string(source.get_track(index).uri); break; case Column.PLAYING: value.init(typeof(bool)); value.set_boolean(Services.playback().current_track != null && source == Services.playback().current_track.source && index == Services.playback().current_track.index); break; case Column.RATING: value.init(typeof(int)); if (source.get_track(index) is IRateableTrack) value.set_int(((IRateableTrack)source.get_track(index)).rating); else value.set_int(-1); break; default: assert_not_reached(); } } public int get_index_from_path(Gtk.TreePath path) { assert(path.get_depth() == 1); assert(path.get_indices()[0] >= 0); assert(path.get_indices()[0] < source.get_num_tracks()); return path.get_indices()[0]; } public Gtk.TreePath get_path_from_index(int index, bool check_index_max = true) { assert(index >= 0); assert(index < source.get_num_tracks() || !check_index_max); return new Gtk.TreePath.from_indices(index, -1); } public int get_index_from_iter(Gtk.TreeIter iter) { assert(iter.stamp == stamp); assert((int)iter.user_data >= 0); assert((int)iter.user_data < source.get_num_tracks()); return (int)iter.user_data; } public void get_iter_from_index(out Gtk.TreeIter iter, int index) { assert(index >= 0); assert(index < source.get_num_tracks()); iter.stamp = stamp; iter.user_data = (void*)index; } public bool get_iter(out Gtk.TreeIter iter, Gtk.TreePath path) { if (path.get_depth() != 1 || path.get_indices()[0] >= source.get_num_tracks()) return false; get_iter_from_index(out iter, get_index_from_path(path)); return true; } public Gtk.TreePath get_path(Gtk.TreeIter iter) { return get_path_from_index(get_index_from_iter(iter)); } public bool iter_next(ref Gtk.TreeIter iter) { int index = get_index_from_iter(iter); if (index < (source.get_num_tracks()-1)) { index++; get_iter_from_index(out iter, index); return true; } return false; } public Gtk.TreeModelFlags get_flags() { return Gtk.TreeModelFlags.LIST_ONLY; } public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent) { return false; } public bool iter_has_child(Gtk.TreeIter iter) { return false; } public int iter_n_children(Gtk.TreeIter? iter) { return 0; } public bool iter_nth_child(out Gtk.TreeIter iter, Gtk.TreeIter? parent, int n) { return false; } public bool iter_parent(out Gtk.TreeIter iter, Gtk.TreeIter child) { return false; } public void ref_node(Gtk.TreeIter iter) { // Do nothing } public void unref_node(Gtk.TreeIter iter) { // Do nothing } }