Initial commit
[jamendo] / src / album_listview.c
diff --git a/src/album_listview.c b/src/album_listview.c
new file mode 100644 (file)
index 0000000..39153df
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * album_listview.c
+ *
+ *  Created on: 2009-10-13
+ *      Author: marcin
+ */
+
+#include <hildon/hildon.h>
+#include "album_listview.h"
+#include "data_structs.h"
+#include "http_utils.h"
+#include "album_screen.h"
+#include "resource_utils.h"
+
+/**
+ * list view column indexes
+ */
+enum {
+       COLUMN_PIXBUF, COLUMN_ALBUM, COLUMN_RATING, COLUMN_ALBUM_PTR, NUM_COLUMNS
+};
+
+/****************************************************************************
+ *
+ */
+
+static void show_album_screen(GtkTreeView* treeview, GtkTreePath* path, gpointer data) {
+       GtkWidget *win;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+       Album *album = NULL;
+
+       model = gtk_tree_view_get_model(treeview);
+       if (gtk_tree_model_get_iter(model, &iter, path)) {
+               gtk_tree_model_get(model,&iter,COLUMN_ALBUM_PTR,&album,-1);
+       }
+
+       if (album) {
+               win = album_screen_new(album);
+               gtk_widget_show_all(win);
+       }
+}
+
+
+/****************************************************************************
+ * album listview functions
+ *l
+ * creates tree view with album graphics and title and artist
+ ****************************************************************************/
+
+typedef struct {
+       GtkTreeModel* model;
+       GtkTreeIter iter;
+       gboolean stop;
+       GThread* thread;
+} LoadImagesData;
+
+static gpointer load_images(LoadImagesData *data) {
+       Album *album = NULL;
+       GdkPixbuf* album_image = NULL;
+       gboolean next = FALSE;
+
+       g_object_ref(data->model);
+       gdk_threads_enter();
+       gtk_tree_model_get_iter_first(data->model, &data->iter);
+       gdk_threads_leave();
+
+       do {
+               gdk_threads_enter();
+               gtk_tree_model_get(data->model, &data->iter, COLUMN_ALBUM_PTR, &album, -1);
+               gdk_threads_leave();
+
+               album_image = http_get_image(album->image, -1, HILDON_ICON_PIXEL_SIZE_THUMB);
+
+               gdk_threads_enter();
+               gtk_list_store_set(GTK_LIST_STORE(data->model), &data->iter, COLUMN_PIXBUF, album_image, -1);
+               next = gtk_tree_model_iter_next(data->model, &data->iter);
+               gdk_threads_leave();
+
+               g_object_unref(album_image);
+               g_boxed_free(G_TYPE_ALBUM, album);
+       } while (next && !data->stop);
+
+       g_object_unref(data->model);
+
+       return NULL;
+}
+
+void album_listview_destroyed(GtkWidget* listview, LoadImagesData* data) {
+       g_debug("album_listview_destroyed join %p data->stop %d",data->thread,data->stop);
+       data->stop = TRUE;
+       gdk_threads_leave();
+       g_thread_join(data->thread);
+       gdk_threads_enter();
+       g_debug("album_listview_destroyed free");
+       g_free(data);
+}
+
+static GdkPixbuf* no_cd_image = 0;
+
+void album_listview_update_model(GtkWidget* listview, GList* album_list) {
+       GtkListStore *store;
+       GtkTreeIter iter;
+       GList* album_iter;
+       gchar* stars[]={"","*","**","***","****","*****"};
+
+       store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(listview)));
+
+       gtk_list_store_clear(store);
+
+       if (!album_list) {
+               return;
+       }
+
+       if (!no_cd_image) {
+               no_cd_image = resource_get_pixbuf_at_scale("no_cd_image.png", -1, HILDON_ICON_PIXEL_SIZE_THUMB);
+       }
+
+       for (album_iter = g_list_first(album_list); album_iter; album_iter = album_iter->next) {
+               Album* album = (Album*) album_iter->data;
+               gchar* album_title = g_markup_printf_escaped("<span size='small'>%s</span>\n<span size='x-small'>%s</span>", album->name, album->artist_name);
+               gchar* album_stars = g_strdup_printf("<span color='orange' size='medium' weight='bold'>%s</span>", stars[(int)(album->rating * 5.0 + 0.5)]);
+               gtk_list_store_append(store, &iter);
+               gtk_list_store_set(store, &iter,
+                               COLUMN_PIXBUF, no_cd_image,
+                               COLUMN_ALBUM, album_title,
+                               COLUMN_RATING, album_stars,
+                               COLUMN_ALBUM_PTR, album,
+                               -1);
+               g_free(album_title);
+               g_free(album_stars);
+       }
+
+       /** images downloaded in background */
+       LoadImagesData* data = g_new0(LoadImagesData,1);
+       data->model = GTK_TREE_MODEL(store);
+       data->thread = g_thread_create((GThreadFunc)load_images, data, TRUE, NULL);
+
+       /* when listview is destroyed, destroy also album_list */
+       g_signal_connect(G_OBJECT(listview), "destroy", G_CALLBACK(album_listview_destroyed), data);
+}
+
+static void album_listview_add_columns(GtkTreeView *treeview) {
+       GtkCellRenderer *renderer;
+       GtkTreeViewColumn *column;
+
+       renderer = gtk_cell_renderer_pixbuf_new();
+       g_object_set(G_OBJECT (renderer), "follow-state", FALSE, NULL);
+
+       column = gtk_tree_view_column_new_with_attributes("Image", renderer, "pixbuf", COLUMN_PIXBUF, NULL);
+       gtk_tree_view_append_column(treeview, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Album", renderer, "markup", COLUMN_ALBUM, NULL);
+       gtk_tree_view_append_column(treeview, column);
+
+       renderer = gtk_cell_renderer_text_new();
+       column = gtk_tree_view_column_new_with_attributes("Rating", renderer, "markup", COLUMN_RATING, NULL);
+       // TODO: width should be calculated runtime
+       gtk_tree_view_column_set_fixed_width(column,60);
+       gtk_tree_view_append_column(treeview, column);
+}
+
+GtkWidget* album_listview_create(GList* album_list) {
+       GtkWidget *listview;
+       GtkTreeModel *model;
+
+       model = GTK_TREE_MODEL( gtk_list_store_new(NUM_COLUMNS, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ALBUM) );
+       listview = gtk_tree_view_new_with_model(model);
+       album_listview_update_model(listview,album_list);
+       g_object_unref(model);
+
+       gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(listview)), GTK_SELECTION_NONE);
+       album_listview_add_columns(GTK_TREE_VIEW(listview));
+
+       g_signal_connect(listview, "hildon-row-tapped", G_CALLBACK(show_album_screen),NULL);
+
+       return listview;
+}
+