Initial commit
[jamendo] / src / radioselector_screen.c
1 /*
2  * radioelector_screen.c
3  *
4  *  Created on: 2009-12-11
5  *      Author: marcin
6  */
7
8 #include <hildon/hildon.h>
9 #include "radioselector_screen.h"
10 #include "data_structs.h"
11 #include "jamendo_api.h"
12 #include "http_utils.h"
13 #include "resource_utils.h"
14 #include "playlist_screen.h"
15
16 /****************************************************************************/
17
18 /**
19  * list view column indexes
20  */
21 enum {
22         COLUMN_PIXBUF, COLUMN_RADIO, COLUMN_RADIO_PTR, NUM_COLUMNS
23 };
24
25 /****************************************************************************
26  *
27  */
28
29 static void show_radio_screen(GtkTreeView* treeview, GtkTreePath* path, gpointer data) {
30         GtkWidget *win;
31         GtkTreeModel *model;
32         GtkTreeIter iter;
33         Radio *radio = NULL;
34
35         model = gtk_tree_view_get_model(treeview);
36         if (gtk_tree_model_get_iter(model, &iter, path)) {
37                 gtk_tree_model_get(model,&iter,COLUMN_RADIO_PTR,&radio,-1);
38         }
39
40         if (radio) {
41                 GList* track_list = jamendo_get_radio_playlist(radio);
42                 win = playlist_screen_new(track_list,radio->name);
43                 gtk_widget_show_all(win);
44         }
45 }
46
47
48 /****************************************************************************
49  * radio listview functions
50  *
51  * creates tree view with radio graphics and name
52  ****************************************************************************/
53
54 typedef struct {
55         GtkTreeModel* model;
56         GtkTreeIter iter;
57         gboolean stop;
58         GThread* thread;
59 } LoadImagesData;
60
61 static gpointer load_images(LoadImagesData *data) {
62         Radio *radio = NULL;
63         GdkPixbuf* radio_image = NULL;
64         gboolean next = FALSE;
65
66         g_object_ref(data->model);
67         gdk_threads_enter();
68         gtk_tree_model_get_iter_first(data->model, &data->iter);
69         gdk_threads_leave();
70
71         do {
72                 gdk_threads_enter();
73                 gtk_tree_model_get(data->model, &data->iter, COLUMN_RADIO_PTR, &radio, -1);
74                 gdk_threads_leave();
75
76                 radio_image = http_get_image(radio->image, -1, HILDON_ICON_PIXEL_SIZE_THUMB);
77
78                 gdk_threads_enter();
79                 gtk_list_store_set(GTK_LIST_STORE(data->model), &data->iter, COLUMN_PIXBUF, radio_image, -1);
80                 next = gtk_tree_model_iter_next(data->model, &data->iter);
81                 gdk_threads_leave();
82
83                 g_object_unref(radio_image);
84                 g_boxed_free(G_TYPE_RADIO, radio);
85         } while (next && !data->stop);
86
87         g_object_unref(data->model);
88
89         return NULL;
90 }
91
92 void radio_listview_destroyed(GtkWidget* listview, LoadImagesData* data) {
93         g_debug("radio_listview_destroyed join %p data->stop %d",data->thread,data->stop);
94         data->stop = TRUE;
95         gdk_threads_leave();
96         g_thread_join(data->thread);
97         gdk_threads_enter();
98         g_debug("radio_listview_destroyed free");
99         g_free(data);
100 }
101
102 static GdkPixbuf* no_cd_image = 0;
103
104 void radio_listview_update_model(GtkWidget* listview, GList* radio_list) {
105         GtkListStore *store;
106         GtkTreeIter iter;
107         GList* radio_iter;
108
109         store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(listview)));
110
111         gtk_list_store_clear(store);
112
113         if (!radio_list) {
114                 return;
115         }
116
117         if (!no_cd_image) {
118                 no_cd_image = resource_get_pixbuf_at_scale("no_cd.png",-1,HILDON_ICON_PIXEL_SIZE_THUMB);
119         }
120
121         for (radio_iter = g_list_first(radio_list); radio_iter; radio_iter = radio_iter->next) {
122                 Radio* radio = (Radio*) radio_iter->data;
123                 gchar* radio_title = g_markup_printf_escaped("<span size='small'>%s</span>", radio->name);
124                 gtk_list_store_append(store, &iter);
125                 gtk_list_store_set(store, &iter,
126                                 COLUMN_PIXBUF, no_cd_image,
127                                 COLUMN_RADIO, radio_title,
128                                 COLUMN_RADIO_PTR, radio,
129                                 -1);
130                 g_free(radio_title);
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 radio_list */
139         g_signal_connect(G_OBJECT(listview), "destroy", G_CALLBACK(radio_listview_destroyed), data);
140 }
141
142 static void radio_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("Radio", renderer, "markup", COLUMN_RADIO, NULL);
154         gtk_tree_view_append_column(treeview, column);
155
156 }
157
158 GtkWidget* radio_listview_create(GList* radio_list) {
159         GtkWidget *listview;
160         GtkTreeModel *model;
161
162         model = GTK_TREE_MODEL( gtk_list_store_new(NUM_COLUMNS, G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_RADIO) );
163         listview = gtk_tree_view_new_with_model(model);
164         radio_listview_update_model(listview,radio_list);
165         g_object_unref(model);
166
167         gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(listview)), GTK_SELECTION_NONE);
168         radio_listview_add_columns(GTK_TREE_VIEW(listview));
169
170         g_signal_connect(listview, "hildon-row-tapped", G_CALLBACK(show_radio_screen),NULL);
171
172         return listview;
173 }
174
175 typedef struct {
176         GtkWidget *win;
177         GtkWidget *listview;
178 } PopulateRadioListParam;
179
180 static guint populate_radio_list(PopulateRadioListParam *param) {
181         GList* radio_list;
182
183         radio_list = jamendo_get_radios();
184         radio_listview_update_model(param->listview, radio_list);
185         radio_list_free(radio_list);
186
187         hildon_gtk_window_set_progress_indicator(GTK_WINDOW(param->win),0);
188         gtk_widget_show_all(param->win);
189
190         g_free(param);
191         return FALSE;
192 }
193
194 /****************************************************************************/
195
196 GtkWidget* radioselector_screen_new() {
197         GtkWidget* win;
198         GtkWidget *treeview;
199         GtkWidget* radio_box;
200
201         /* Create the main window */
202         win = hildon_stackable_window_new();
203         gtk_window_set_title(GTK_WINDOW(win), "Radios");
204
205         //player_set_radio_list(radio_list);
206         treeview = radio_listview_create(NULL);
207
208         radio_box = hildon_pannable_area_new();
209         hildon_pannable_area_add_with_viewport(HILDON_PANNABLE_AREA(radio_box), treeview);
210
211         GtkWidget* main_box = gtk_hbox_new(TRUE,0);
212         gtk_box_pack_start(GTK_BOX(main_box), radio_box, TRUE,TRUE,0);
213         gtk_container_add(GTK_CONTAINER(win), main_box);
214
215         hildon_gtk_window_set_progress_indicator(GTK_WINDOW(win),1);
216         hildon_banner_show_information(win,NULL,"Downloading");
217
218         PopulateRadioListParam* param = g_new0(PopulateRadioListParam,1);
219         param->win = win;
220         param->listview = treeview;
221         gdk_threads_add_idle((GSourceFunc)populate_radio_list, param);
222
223         //hildon_program_add_window(hildon_program_get_instance(),HILDON_WINDOW(win));
224         //gtk_widget_hide(player_toolbar_create());
225
226         return win;
227 }