Archive / / / / / Echo.Core.Playlist.vala
2008-12-02 06:31:21 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.Interfaces; public class Echo.Core.Playlist : GLib.Object, IPlaySource, IModPlaySource { // TODO set up Playlist to forward track_changed events from sources which have tracks // that are in this playlist private string _name; private Gee.ArrayList<PlaylistTrack> _tracks; public string name { get { return _name; } } public string icon { get { return "text-x-generic"; } } public Playlist(string name) { _name = name; _tracks = new Gee.ArrayList<PlaylistTrack>(); } public int get_num_tracks() { return _tracks.size; } public weak ITrack get_track(int index) { assert(index >= 0); assert(index < get_num_tracks()); ITrack track = _tracks.get(index); return track; } public void insert_track(int index, ITrack track) { assert(index >= 0); assert(index <= get_num_tracks()); // <= because it could be at the end while (track is PlaylistTrack) track = ((PlaylistTrack)track).get_real_track(); _tracks.insert(index, new PlaylistTrack(this, index, track)); for (int i = index; i < _tracks.size; i++) _tracks.get(i).set_index(i); this.track_inserted(index); } public void remove_track(int index) { assert(index >= 0); assert(index < get_num_tracks()); _tracks.get(index).invalidate(); _tracks.remove_at(index); for (int i = index; i < _tracks.size; i++) _tracks.get(i).set_index(i); this.track_removed(index); } public void move_track(int old_index, int new_index) { assert(old_index >= 0); assert(old_index < get_num_tracks()); assert(new_index >= 0); assert(new_index <= get_num_tracks()); // <= because it could be at the end var track = _tracks.get(old_index); _tracks.remove_at(old_index); for (int i = old_index; i < _tracks.size; i++) _tracks.get(i).set_index(i); this.track_removed(old_index); if (old_index < new_index) new_index--; _tracks.insert(new_index, track); for (int i = new_index; i < _tracks.size; i++) _tracks.get(i).set_index(i); this.track_inserted(new_index); } private class PlaylistTrack : GLib.Object, ITrack { public IPlaySource source { get { return _playlist; } } private int _index; public int index { get { return _index; } } public string title { get { return _real_track.title; } } public string artist { get { return _real_track.artist; } } public string album { get { return _real_track.album; } } public int track_number { get { return _real_track.track_number; } } public int release_year { get { return _real_track.release_year; } } public int release_month { get { return _real_track.release_month; } } public int release_day { get { return _real_track.release_day; } } public string uri { get { return _real_track.uri; } } private Playlist _playlist; private ITrack _real_track; private bool _valid = true; public PlaylistTrack(Playlist playlist, int index, ITrack real_track) { _playlist = playlist; _index = index; _real_track = real_track; _real_track.track_invalidated += (ITrack) => { _valid = false; this.track_invalidated(); }; } public void set_index(int index) { _index = index; } public ITrack? get_next() { int i = this.index + 1; if (i >= 0 && i < _playlist.get_num_tracks()) return _playlist.get_track(i); else return null; } public ITrack? get_prev() { int i = this.index - 1; if (i >= 0 && i < _playlist.get_num_tracks()) return _playlist.get_track(i); else return null; } public weak ITrack get_real_track() { return _real_track; } public void invalidate() { _valid = false; this.track_invalidated(); } public bool valid { get { return _valid; } } } /* public IPlaySourceTrackRef get_track_ref(int index) { return new PlaylistIterator(this, index); } private class PlaylistIterator : GLib.Object, IPlaySourceTrackRef { private Playlist _playlist; private int _index; private bool _valid; public PlaylistIterator(Playlist playlist, int index) { _playlist = playlist; _index = index; _valid = true; // TODO check that these functions are automatically detached from the signal // when the iterator is freed _playlist.track_removed += (playlist, removed_index) => { if (removed_index < _index) _index--; else if (removed_index == _index) { _valid = false; this.track_invalidated(); } }; _playlist.track_inserted += (playlist, inserted_index) => { if (inserted_index <= _index) _index++; }; } public bool next() { if (!_valid) return false; if (_index < _playlist.get_num_tracks()) _index++; return (_index < _playlist.get_num_tracks()); } public bool prev() { if (!_valid) return false; if (_index >= 0) _index--; return (_index >= 0); } public weak Track? get() { if (!_valid) return null; if (_index >= 0 && _index < _playlist.get_num_tracks()) return _playlist.get_track(_index); else return null; } public IPlaySource? get_source() { if (!_valid) return null; else return _playlist; } public int get_index() { if (!_valid || _index < 0 || _index >= _playlist.get_num_tracks()) return -1; else return _index; } }*/ }