5
public class BeatBox.FilterView : ScrolledWindow {
13
private Collection<int> showingSongs;
14
private string last_search;
15
LinkedList<string> timeout_search;
19
public bool isCurrentView;
20
public bool needsUpdate;
22
public signal void itemClicked(string artist, string album);
24
/* songs should be mutable, as we will be sorting it */
25
public FilterView(LibraryManager lmm, LibraryWindow lww, LinkedList<int> ssongs) {
30
showingSongs = new LinkedList<int>();
32
timeout_search = new LinkedList<string>();
34
defaultPath = GLib.Path.build_filename("/usr", "share", "icons", "hicolor", "128x128", "mimetypes", "media-audio.svg", null);
39
public void buildUI() {
41
Viewport v = new Viewport(null, null);
43
set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
45
view.settings.enable_default_context_menu = false;
47
v.set_shadow_type(ShadowType.NONE);
53
view.navigation_requested.connect(navigationRequested);
54
lw.searchField.changed.connect(searchFieldChanged);
57
/** Goes through the hashmap and generates html. If artist,album, or genre
58
* is set, makes sure that only items that fit those filters are
61
public void generateHTML(LinkedList<Song> toShow) {
63
/** NOTE: This could have a bad effect if user coincidentally
64
* searches for something that has same number of results as
65
* a different search. However, this cuts lots of unecessary
66
* loading of lists/icon lists */
67
if(showingSongs.size == toShow.size)
70
string html = """<!DOCTYPE html> <html lang="en"><head>
71
<style media="screen" type="text/css">
74
font-family: "Droid Sans",sans-serif;
88
display: inline-block;
89
list-style-type: none;
107
</style></head><body><div id="main"><ul>""";
109
// first sort the songs so we know they are grouped by artists, then albums
110
toShow.sort((CompareFunc)songCompareFunc);
112
string previousAlbum = "";
113
foreach(Song s in toShow) {
114
if(s.album != previousAlbum) {
115
html += "<li><a href=\"" + s.album + "<seperater>" + s.artist + "\"><img width=\"150\" height=\"150\" src=\"file://" + s.getAlbumArtPath() + "\" /></a><p>" + ( (s.album == "") ? "Unknown" : s.album) + "</p><p>" + s.artist + "</p></li>";
116
previousAlbum = s.album;
120
html += "</ul></div></body></html>"; // finish up the last song, finish up html
122
view.load_html_string(html, "file://");
125
showingSongs = toShow;
128
public static int songCompareFunc(Song a, Song b) {
129
if(a.artist.down() == b.artist.down())
130
return (a.album.down() > b.album.down()) ? 1 : -1;
132
return (a.artist.down() > b.artist.down()) ? 1 : -1;
135
public virtual NavigationResponse navigationRequested(WebFrame frame, NetworkRequest request) {
136
if(request.uri.contains("<seperater>")) {
138
string[] splitUp = request.uri.split("<seperater>", 0);
140
itemClicked(splitUp[0], splitUp[1]);
142
return WebKit.NavigationResponse.IGNORE;
145
return WebKit.NavigationResponse.ACCEPT;
148
public virtual void searchFieldChanged() {
149
if(isCurrentView && lw.searchField.get_text().length != 1) {
150
timeout_search.offer_head(lw.searchField.get_text().down());
151
Timeout.add(100, () => {
152
string to_search = timeout_search.poll_tail();
153
stdout.printf("searching for %s\n", to_search);
155
if(timeout_search.size == 0) {
156
var toSearch = new LinkedList<Song>();
157
foreach(int id in lm.songs_from_search(to_search, "All Genres",
162
toSearch.add(lm.song_from_id(id));
165
if(showingSongs.size != toSearch.size) {
166
generateHTML(toSearch);