Cleanup.
[jamendo] / src / album_listview.c
1 /*
2  * album_listview.c
3  *
4  *  Created on: 2009-10-13
5  *      Author: marcin
6  */
7
8 #include <hildon/hildon.h>
9 #include "album_listview.h"
10 #include "data_structs.h"
11 #include "http_utils.h"
12 #include "album_screen.h"
13 #include "resource_utils.h"
14
15 /**
16  * list view column indexes
17  */
18 enum {
19         COLUMN_PIXBUF, COLUMN_ALBUM, COLUMN_RATING, COLUMN_ALBUM_PTR, NUM_COLUMNS
20 };
21
22 /****************************************************************************
23  *
24  */
25
26 static void show_album_screen(GtkTreeView* treeview, GtkTreePath* path, gpointer data) {
27         GtkWidget *win;
28         GtkTreeModel *model;
29         GtkTreeIter iter;
30         Album *album = NULL;
31
32         model = gtk_tree_view_get_model(treeview);
33         if (gtk_tree_model_get_iter(model, &iter, path)) {
34                 gtk_tree_model_get(model,&iter,COLUMN_ALBUM_PTR,&album,-1);
35         }
36
37         if (album) {
38                 win = album_screen_new(album);
39                 gtk_widget_show_all(win);
40         }
41 }
42
43
44 /****************************************************************************
45  * album listview functions
46  *l
47  * creates tree view with album graphics and title and artist
48  ****************************************************************************/
49
50 typedef struct {
51         GtkTreeModel* model;
52         GtkTreeIter iter;
53         gboolean stop;
54         GThread* thread;
55 } LoadImagesData;
56
57 static gpointer load_images(LoadImagesData *data) {
58         Album *album = NULL;
59         GdkPixbuf* album_image = NULL;
60         gboolean next = FALSE;
61
62         g_object_ref(data->model);
63         gdk_threads_enter();
64         gtk_tree_model_get_iter_first(data->model, &data->iter);
65         gdk_threads_leave();
66
67         do {
68                 gdk_threads_enter();
69                 gtk_tree_model_get(data->model, &data->iter, COLUMN_ALBUM_PTR, &album, -1);
70                 gdk_threads_leave();
71
72                 album_image = http_get_image(album->image, -1, HILDON_ICON_PIXEL_SIZE_THUMB);
73
74                 gdk_threads_enter();
75                 gtk_list_store_set(GTK_LIST_STORE(data->model), &data->iter, COLUMN_PIXBUF, album_image, -1);
76                 next = gtk_tree_model_iter_next(data->model, &data->iter);
77                 gdk_threads_leave();
78
79                 g_object_unref(album_image);
80                 g_boxed_free(G_TYPE_ALBUM, album);
81         } while (next && !data->stop);
82
83         g_object_unref(data->model);
84
85         return NULL;
86 }
87
88 void album_listview_destroyed(GtkWidget* listview, LoadImagesData* data) {
89         g_debug("album_listview_destroyed join %p data->stop %d",data->thread,data->stop);
90         data->stop = TRUE;
91         gdk_threads_leave();
92         g_thread_join(data->thread);
93         gdk_threads_enter();
94         g_debug("album_listview_destroyed free");
95         g_free(data);
96 }
97
98 static GdkPixbuf* no_cd_image = 0;
99
100 void album_listview_update_model(GtkWidget* listview, GList* album_list) {
101         GtkListStore *store;
102         GtkTreeIter iter;
103         GList* album_iter;
104         gchar* stars[]={"","*","**","***","****","*****"};
105
106         store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(listview)));
107
108         gtk_list_store_clear(store);
109
110         if (!album_list) {
111                 return;
112         }
113
114         if (!no_cd_image) {
115                 no_cd_image = resource_get_pixbuf_at_scale("no_cd_image.png", -1, HILDON_ICON_PIXEL_SIZE_THUMB);
116         }
117
118         for (album_iter = g_list_first(album_list); album_iter; album_iter = album_iter->next) {
119                 Album* album = (Album*) album_iter->data;
120                 gchar* album_title = g_markup_printf_escaped("<span size='small'>%s</span>\n<span size='x-small'>%s</span>", album->name, album->artist_name);
121                 gchar* album_stars = g_strdup_printf("<span color='orange' size='medium' weight='bold'>%s</span>", stars[(int)(album->rating * 5.0 + 0.5)]);
122                 gtk_list_store_append(store, &iter);
123                 gtk_list_store_set(store, &iter,
124                                 COLUMN_PIXBUF, no_cd_image,
125                                 COLUMN_ALBUM, album_title,
126                                 COLUMN_RATING, album_stars,
127                                 COLUMN_ALBUM_PTR, album,
128                                 -1);
129                 g_free(album_title);
130                 g_free(album_stars);
131         }
132
133         /** images downloaded in background */
134         LoadImagesData* data = g_new0(LoadImagesData,1);
135         data->model = GTK_TREE_MODEL(store);
136         data->thread = g_thread_create((GThreadFunc)load_images, data, TRUE, NULL);
137
138         /* when listview is destroyed, destroy also album_list */
139         g_signal_connect(G_OBJECT(listview), "destroy", G_CALLBACK(album_listview_destroyed), data);
140 }
141
142 static void album_listview_add_columns(GtkTreeView *treeview) {
143         GtkCellRenderer *renderer;
144         GtkTreeViewColumn *column;
145
146         renderer = gtk_cell_renderer_pixbuf_new();
147         g_object_set(G_OBJECT (renderer), "follow-state", FALSE, NULL);
148
149         column = gtk_tree_view_column_new_with_attributes("Image", renderer, "pixbuf", COLUMN_PIXBUF, NULL);
150         gtk_tree_view_append_column(treeview, column);
151
152         renderer = gtk_cell_renderer_text_new();
153         column = gtk_tree_view_column_new_with_attributes("Album", renderer, "markup", COLUMN_ALBUM, NULL);
154         gtk_tree_view_append_column(treeview, column);
155
156         renderer = gtk_cell_renderer_text_new();
157         column = gtk_tree_view_column_new_with_attributes("Rating", renderer, "markup", COLUMN_RATING, NULL);
158         // TODO: width should be calculated runtime
159         gtk_tree_view_column_set_fixed_width(column,60);
160         gtk_tree_view_append_column(treeview, column);
161 }
162
163 GtkWidget* album_listview_create(GList* album_list) {
164         GtkWidget *listview;
165         GtkTreeModel *model;
166
167         model = GTK_TREE_MODEL( gtk_list_store_new(NUM_COLUMNS, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ALBUM) );
168         listview = gtk_tree_view_new_with_model(model);
169         album_listview_update_model(listview,album_list);
170         g_object_unref(model);
171
172         gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(listview)), GTK_SELECTION_NONE);
173         album_listview_add_columns(GTK_TREE_VIEW(listview));
174
175         g_signal_connect(listview, "hildon-row-tapped", G_CALLBACK(show_album_screen),NULL);
176
177         return listview;
178 }
179